Pardon Templates
Endpoints
Section titled “Endpoints”Pardon endpoints are represented with https files. Each API call for services you’ve setup to be called by pardon should be represented by a single endpoint, ideally any sufficiently-specified request should match a single endpoint: this means that the input HTTP request should only potentially merge with a single endpoint.
Endpoint Files
Section titled “Endpoint Files”Endpoints are organized in collection folders. Inside a collection
folder, subfolders define
different services, and each subfolder should contain a service.yaml
to identify it.
The name of the subfolder is the service
.
Endpoints Configuration
Section titled “Endpoints Configuration”In the introduction we specified requests to https://todo.example.com/...
, while in the quickstart
we configured this with env=local
to change the request origin. In other popular HTTP frameworks,
this would require defining the request collection with something like {{origin}}/todos/{{todo}}
,
making the collection dependent on a separately maintained environment to be functional.
In Pardon we can configure the requests with map that binds different values of env
to different
values of origin
.
config: origin: env: local: http://localhost:{{port=8080}} stage: http://todos-stage.example.com prod: http://todos.example.com
(we can define these per-endpoint, but generally the origin config would go into a service.yaml
.)
Configuring origin
works because the HTTP request is parsed to match the origin in the URL with {{origin}}
.
Any template-interpolated value can be configured this way.
When matching a request to an endpoint, the origin
must be compatible with one of these
alternatives, but a value for env
could override the matched origin.
For example, a request to stage can be specified with a direct match to the stage origin
GET https://todos-stage.example.com/todos
or we can use the production origin and override env
env=stageGET https://todos.example.com/todos
In both cases the intent of the request is clear.
When making requests to our local applications, we can use env=local
and, optionally, also define
port
if the default specified in http://localhost:{{port=8080}}
is not right for us, or we can
specify the service value, as in service=todo GET http://localhost:8080/todos/...
, because otherwise
the localhost domain isn’t enough to identify what service we’re calling.
Specifying a value for service
restricts the endpoints that are considered to the todo service,
making the origin unnecessary for identifing it.
Complex Configuration
Section titled “Complex Configuration”More layers of configuration can be incorporated into the config mapping.
config: origin: env: local: http://localhost:{{port=8080}} stage: region: auto: https://todos-stage.example.com east: https://todos-stage-east.example.com west: https://todos-stage-west.example.com prod: region: auto: https://todos.example.com east: https://todos-east.example.com west: https://todos-west.example.comdefaults: region: auto
This binds the origin configuration to two other values: the value of env
and the value of region
.
The defaults mapping can supply default values. Defaults can be keyed on other values similar to the config.
A request to https://todos-east.example.com/todos
naturally implies env=prod
and region=east
,
while env=stage https://todos-east.example.com/todos
becomes
https://todos-stage-east.example.com/todos
(keeping the region value) and region=west https://todos-east.example.com/todos
becomes https://todos-west.example.com/todos
(keeping the env value), etc.
Mixins, Defaults and Configuration
Section titled “Mixins, Defaults and Configuration”Once an endpoint is matched and selected, we apply its mixins in order. Mixins are additional endpoint configurations which are merged into the request.
Config + defaults can be used to create opt-in and opt-out mixins.
An opt-out mixin will have a config compatible with defaults, and x=any_other_value_than_enabled
would be used to disable it.
config: x: enableddefaults: x: enabled>>>...
While an opt-in mixin will have a config incompatible with defaults, and x=enabled
must be specified
for the mixin to apply.
config: x: enableddefaults: x: disabled>>>...
As mixins apply, defaults are aggregated (but not overridden), and the same configuration key (with specific values for each mixin) can be used to select one-of-many options.
Endpoint Layering
Section titled “Endpoint Layering”Endpoint files are mixins which are bundled together by their path/identity.
As an example, you can have a base todo-service/collection/todo/todos/create.https
file
>>>POST https://todo.example.com/todos/{{todo}}
{ task, done: done.$optional }
And maybe a todo-service-ext/collection/todo/todos/create.https
file like
>>>POST https://todo.example.com/todos/{{todo}}
{ priority: priority.$optional }
This adds the capability to parameterize the todo request with a priority=asap
value, and also to remember the priority
of a request if a priority
value (or field) is specified. (previous requests can be looked up by values).
When matching the endpoint, all of the endpoint layers must merge with the request. Mixins can be similarly layered, and a mixin (by identity) is only applied if all of the mixin layers merge with the request.
The order of application of templates is “endpoint < request”, “endpoint < mixin1 < request”, “endpoint < mixin1 < mixin2 < request”, etc… keeping any mixins that successfully merge: only rendering the final result after all applicable mixins are merged.