HTTP API Gateway Specification
An API Gateway specification is a document that tells Bondy how to route incoming HTTP requests to your WAMP APIs or to external HTTP/REST APIs.
Overview
An API Gateway Specification document is a JSON data structure that declaratively defines an HTTP/REST API and how Bondy should handle each HTTP Request e.g. by converting it into a WAMP operation or forwarding it to an upstream (external) HTTP/REST API. This includes capabilities for data transformation.
A declarative Finite State Machine (FSM)
In effect, an API Gateway Specification is a declarative definition of an API Gateway Finite State Machine that exposes an HTTP/REST API and converts its nouns and verbs to either WAMP or other HTTP/REST actions.
With this approach you can create a whole HTTP/REST API from scratch without any coding.
The API Gateway Specification document has a structure represented by the following object tree:
- API Object
- Version Object 1
- Path Object 1
HTTP METHOD- ... other HTTP methods
- ... other path objects
- Path Object 1
- ... other version objects
- Version Object 1
The following diagram shows the object tree in detail, including all properties and types.

The properties of the objects in the object tree can contain static values and/or dynamically evaluated values via expressions that are resolved against the HTTP request data at runtime.
FSM State
The API Context is the state of the API Gateway FSM. It is incrementally and recursively constructed.
So an API Gateway Specification is the basis of an API Context but also it is evaluated against it, primarily because the context will contain the Request Object at runtime.
The key to the definition of an API Gateway Specification is understanting the API Context, since defining a specification implies writing expressions that target (read and/or update) the context.
On the Open API standard
Open API (formerly Swagger) defines a standard on how HTTP APIs are described, not its implementation. An API Gateway Specification describes an API and the behaviour of the Gateway, that is, it also defines its implementation in terms of the actions that the Gateway performs.
API Context
The API context is a map data structure created by the API Gateway. At runtime, it contains the HTTP Request data as well as the results of parsing and evaluating the definitions and expressions defined in an API Gateway Specification.
The context contains the following keys:
requestThe contents (data and metadata) of the HTTP request being evaluated. The request data is available at runtime, so any expression defined during design time will result in a promise that will be evaluated to a value when handling the HTTP request.
securityThe identity of the authenticated caller. The gateway sets it at runtime, after it authenticates the request with an OAuth2 token, so an expression that reads it is a promise. It holds realm_uri, session, client_id, authid, username (same value as authid), authmethod, groups, locale and meta. The authentication scheme itself is set by the Security Object, not by this key.
actionAt runtime, it will contain the result or error of the action performed by the API Gateway during the handling of an HTTP request.
variablesA mapping of arbitrary variable names to values or expressions. Each entry in this map is obtained during the parsing of the API Object tree. At each level of the tree this property will merge in the values of the target object's variables property, so children nodes can access the entries defined in the ancestors, override them and/or add new variables to the context.
defaultsA mapping of object properties to their default values. Each entry in this map is obtained during the parsing of the API Object tree. At each level of the tree this property will merge in the values of the target object's defaults property, so children nodes can access the entries defined in the ancestors, override them and/or add new defaults to the context. Expressions in the defaults mapping can reference variables in the variables property.
status_codesA mapping of error URIs to HTTP status codes. Bondy initialises it from the default HTTP status of each URI in the error catalogue. The API Object status_codes entries override it, and so do the Version Object entries for that version's paths. Only an expression that reads this map uses it; see Status Codes.
Request Object
The object represents the contents (data and metadata) of an HTTP request. At runtime, the API Gateway writes this object in the API Context request property.
idA unique tracing identifier for the request, in W3C trace-id form: 32 hexadecimal characters.
methodThe HTTP method of the request. One of the following values:
deletegetheadoptionspatchpostput
schemeAn array of strings where values can be: http or https.
peernameA string representation of the requester IP address and port number e.g. 127.0.0.1:54678.
pathThe relative path of the request.
hostThe hostname of the request.
portThe port number of the request.
headersA mapping of HTTP headers to their corresponding values.
languageThe requested language.
query_stringThe HTTP query string. See query_params.
query_paramsA map of query params to values. This is the result of parsing the request's query_string.
Examples:
| Request | Property Value |
|---|---|
GET /users?region=us&type=individual |
{"region": "us", "type": "individual"} |
GET /users?x=100&y=200 |
{"x": "100", "y": "200"} |
bindingsA map of path variable bindings. Bindings occur when the Path Object contains patterns.
Examples: For the path specification /accounts/:acc_id/users/:user_id
| Request | Property Value |
|---|---|
GET /accounts/001/users/002 |
{"acc_id": "001", "user_id": "002"} |
bodyThe body of the request. This is the result of decoding the HTTP body using the encoding determined by the Path Object accepts property which defines the content-types allowed for POST, PUT and PATCH.
body_lengthThe length of the body in bytes.
You access the values in this object by writing expressions using the API Specification expression language.
Result Object
WAMP Result
The result for a WAMP Action.
This object will be accessible with the expression {{action.result}}.
request_idThe WAMP RESULT.id.
detailsThe WAMP RESULT.details.
argsThe WAMP RESULT.args.
kwargsThe WAMP RESULT.kwargs.
HTTP Forward Result
The result of a Forward Action whose upstream responded with a status code below 400.
This object will be accessible with the expression {{action.result}}.
{
"status_code": 200,
"headers": { "content-type": "application/json" },
"body": "...",
"uri": ""
}uri is the upstream response's Location header, if it sent one, or an empty string otherwise.
Error Object
The shape of {{action.error}} when an action fails, for either a WAMP Action or a Forward Action.
For a WAMP action, the error is the called procedure's own WAMP ERROR message, with an added status_code. Bondy derives status_code from error_uri through the default HTTP status of the error catalogue, not through the specification's status_codes map:
{
"error_uri": "com.example.error.not_found",
"args": ["The requested resource was not found."],
"kwargs": {},
"details": {},
"status_code": 404
}For a Forward Action whose upstream responded with a status code of 400 or above, the error is the raw upstream response:
{
"status_code": 404,
"headers": { "content-type": "application/json" },
"body": "..."
}Expression Language
Most API Specification object properties support expressions using an embedded logic-less domain-specific language (internally called "Mops") for data transformation and dynamic configuration.
This same language is also used by the Broker Bridge Specification.
The expression language operates on the API Context and it works by expanding keys (or key paths) provided in a context object and adding or updating keys in the same context object.
Let's assume that we receive the following HTTP request:
curl -X "POST" "http://localhost:18080/accounts/" \
-H 'Content-Type: application/json; charset=utf-8' \
-H 'Accept: application/json; charset=utf-8' \
--data-binary '{
"id" : 12345
"sku" : "ZPK1972",
"price" : 13.99,
"customer": {
"first_name": "John",
"last_name": "Doe",
"email" : "john.doe@foo.com"
},
"ship_to": {
"first_name": "May",
"last_name": "Poppins",
"address" : "3 High Street",
"town" : "Guildford",
"county" : "Surrey",
"zip" : "GU1 1AF"
},
"bill_to": {
"first_name": "John",
"last_name": "Doe",
"address" : "13 Sandy Lane",
"town" : "Esher",
"county" : "Surrey",
"zip" : "KT11 2PQ"
}
}'Let's explore a some example to demonstrate how you can use expression in Bondy's configuration objects to read data from the HTTP Request.
The following table shows some example expressions being evaluated against the API Context for the above HTTP Request.
| Expression String | Evaluates To |
|---|---|
{{request.method}} | POST |
{{request.body}} | {"id": 12345, "bill_to":...} |
{{request.body.sku}} | "ZPK1972" |
"The sku number is {{request.body.sku}}" | "The sku number is ZPK1972" |
{{request.body.price}} | 13.99 |
{{request.body.price |> integer}} | 13 |
{{request.body.customer.first_name}} | "John" |
"{{request.body.customer.first_name}} {{request.body.customer.last_name}}" | "John Doe" |
{{variables.foo}} | Returns the value of the foo variable |
{{status_codes}} | Returns the status codes map |
Learn more
Expressions also allow to set values in the context and use functions to manipulate the request data. Learn more about expressions in the API Specification Expressions reference section.
Specification Evaluation
Incremental Evaluation
The API Specification evaluation performed incrementally in two stages:
- During loading, validation and parsing. All API Specification expressions will be evaluated to either a (final) value or a
promise. Promises occur when an expression depends directly or indirectly (transitive closure) on HTTP request data. This results in a context object. - During HTTP request handling at runtime. The context created in the first stage is updated with the HTTP request data and the API Specification is evaluated again using the updated context, yielding the actions to be performed with all promises evaluated to values (grounded).
Recursive Evaluation
The evaluation of the expressions in the API Gateway Specification is done by passing the API Context recursively throughout the specification object tree.
At each level of the tree children nodes can can use the values of the certain properties defined in the ancestor node (through expressions), override them and/or update the API Context.
Validation
Each object accepts only the properties listed for it on this page, under any of their names. The parser refuses a specification that has any other key in one of these places:
- the API, Version, Path and Operation objects;
- an Action Object, according to its
type; - the
on_resultandon_errorobjects of a Response Object; - the
defaultsof the API, a version or a path; - a Security Object, according to its
type.
A misspelt key is therefore refused, not replaced by its default. The info object of a version or an operation is the exception: it is free-form, and the parser checks only that it is an object.
API Object
The API object is the root of an API Specification. It contains one or more API Version objects.
idA global unique identifier for this API.
hostA string used for matching the incoming HTTP request HOST header value. Hosts with and without a trailing dot are equivalent for routing. Similarly, hosts with and without a leading dot are also equivalent e.g. cowboy.example.org, cowboy.example.org. and .cowboy.example.org are equivalent. A pattern using the keyword : and wildcard _ can be used to match multiple domains e.g. mydomain.:_ will match mydomain.foo and mydomain.bar but not mydomain.foo.baz. Bondy serves the specification's paths only to requests whose host matches. See Request matching.
realm_uriThe realm this API will target. An API can only target a single realm.
nameA display name for the API.
metaA mapping of metadata keys to values.
variablesA mapping of arbitrary variable names to values or expressions. This variables can be referenced by expressions in the children objects of this object.
defaultsA mapping of attributes to their default values. This values are inherited by children objects as defaults when their value is unset.
status_codesA mapping of WAMP Error URIs to HTTP Status Codes. This values are inherited by children objects as defaults when their value is unset.
versionsA mapping of version names to Version Object instances.
API Object example
{
"id": "example-api",
"name" : "Bonding in HTTP",
"host" : "_",
"realm_uri" : "com.example.public",
"meta": {"foo" : "bar"},
"variables" : {
"cors_headers": {
"access-control-allow-origin": "*",
"access-control-allow-credentials": "true",
"access-control-allow-methods": "GET,HEAD,OPTIONS,PUT,PATCH,POST,DELETE",
"access-control-allow-headers": "origin,x-requested-with,content-type,accept,authorization,accept-language",
"access-control-max-age": "86400"
}
},
"defaults" : {
"schemes" : ["http"]
},
"status_codes": {
"com.example.error.not_found": 404,
"com.example.error.unknown_error": 500,
"com.example.error.internal_error": 500
},
"versions" : {
...
}
}Request matching
Bondy serves the paths of a specification only to requests whose host matches the specification's host.
When more than one host, or more than one path, matches a request, the most specific one answers it. At the first segment where two hosts or two paths differ in kind, a literal segment wins over a binding such as :id, and a binding wins over [...]. The host or path _ comes last. Bondy compares hosts from the top-level domain.
Bondy's own paths, such as /ping and /metrics, belong to the host _. When a specification declares one of these paths, the outcome depends on the specification's host:
- With the host
_, Bondy's own path answers the request. - With any other host, the specification's path answers requests for that host.
When two specifications declare the same path for the same host, only one of them answers it. In each of these cases Bondy logs a warning and serves the other paths of the specification.
Bondy serves a specification's paths only while its realm exists. When the realm is deleted, its specifications stay stored and their paths stop being served. After the realm is created again, the next rebuild of the routes on a node serves them again on that node. Loading or deleting any specification triggers a rebuild.
Version Object
The Version Object represents a particular API version.
base_pathThe base path for this version of the API. This value will be used by the API Gateway to match incoming requests e.g. /v1.0 will match /v1.0/foo but not /foo. It is possible to have optional segments, anything between brackets is optional e.g. /[v1.0] will match /v1.0/foo and also /foo.
pathsA mapping of paths to Path Objects. Paths are relative URL paths and can contain patterns and optional segments. The path / is invalid while the path /ws is reserved (used by Bondy for requesting Websocket connections).
is_activeWhether Bondy serves the paths of this version. When false, Bondy adds no route for the version.
trueis_deprecatedWhether the path is deprecated i.e. the path will be removed in future versions of the API.
falsepool_sizeThe parser accepts this key. Bondy does not use its value.
200infoFree-form information about this version, such as a title and a description. The parser checks only that the value is an object, and keeps its keys.
variablesA mapping of arbitrary variable names to values or expressions. This variables can be referenced by expressions in the children objects of this object. These values are merged with and thus override the ones inherited from the API Object variables property.
defaultsA mapping of attributes to their default values. This values are inherited by children objects as defaults when their value is unset. These values are merged with and thus override the ones inherited from the API Object defaults property.
status_codesA mapping of WAMP Error URIs to HTTP Status Codes.
languagesAn array of language code string.
Version Object example
{
"base_path": "/[v1.0]",
"is_active": true,
"is_deprecated": false,
"languages": ["en"],
"info": {
"title": "Marketplace API v1.0",
"description": "Version 1.0 of the Marketplace demo API."
},
"defaults": {
"timeout": 20000
},
"status_codes": {
"com.example.error.not_found": 404,
"com.example.error.internal_error": 500
},
"paths": {
"/services/echo": {
"get": { }
}
}
}Path Object
A path specification to be used as a value to a key in the paths property of a Version Object.
summaryA short summary of the API.
descriptionA description of the API.
variablesA mapping of arbitrary variable names to values or expressions. This variables can be referenced by expressions in the children objects of this object. These values are merged with and thus override the ones inherited from the API Object variables property.
defaultsA mapping of attributes to their default values or a MOPS expression resolving to such a map. This values are inherited by children objects as defaults when their value is unset. These values are merged with and thus override the ones inherited from the API Object default property.
is_collectionDefines whether the resource managed in this path is a collection or not.
falseacceptsAn array of content types. The supported content types are:
application/jsonapplication/json; charset=utf-8application/msgpackapplication/msgpack; charset=utf-8application/x-www-form-urlencoded
defaults.acceptsprovidesAn array of content types. The supported content types are:
application/jsonapplication/json; charset=utf-8application/msgpackapplication/msgpack; charset=utf-8
defaults.providesschemesAn array of strings where values can be: http or https.
defaults.schemessecuritydefaults.securitydeleteThe operation specification to perform in case the API Gateway receives an HTTP DELETE Request.
getThe operation specification to perform in case the API Gateway receives an HTTP GET Request.
headThe operation specification to perform in case the API Gateway receives an HTTP HEAD Request.
optionsThe operation specification to perform in case the API Gateway receives an HTTP OPTIONS Request.
patchThe operation specification to perform in case the API Gateway receives an HTTP PATCH Request.
postThe operation specification to perform in case the API Gateway receives an HTTP POST Request.
putThe operation specification to perform in case the API Gateway receives an HTTP PUT Request.
Path Object example
{
"id": "example-api",
...,
"versions" : {
"base_path": "v1.0",
...,
"paths" : {
"/path/to/resource" : {
"get" : {
...
},
"post" : {
...
}
},
"/path/to/:resourceId" : {
"get" : {
...
},
"post" : {
...
}
},
"/path/to/other/resource" : {
"get" : {
...
},
"post" : {
...
}
}
}
}
}Operation Object
actionresponseinfoFree-form information about this operation. The parser checks only that the value is an object, and keeps its keys.
body_max_bytesdefaults.body_max_bytesbody_read_bytesdefaults.body_read_bytesbody_read_secondsdefaults.body_read_secondsOperation Object example
{
"info": {"summary": "Echoes the request body back to the caller."},
"body_max_bytes": 1048576,
"action": {
"type": "static",
"body": "{{request.body}}"
},
"response": {
"on_result": {
"body": "{{action.result}}"
}
}
}Action Object
The API Gateway supports four types of action: static, forward, wamp_call and wamp_publish.
Static Action
An action that returns a static response.
typeThe value static.
headersA mapping of HTTP headers to their corresponding values.
bodyThe body to be returned with the response.
Static Action example
{
"type": "static",
"headers": {
"content-type": "application/json"
},
"body": {
"status": "operational",
"version": "1.0.0"
}
}Forward Action
An action that forwards the incoming HTTP request to an upstream HTTP endpoint.
typeThe value forward.
http_methodThe HTTP method to be used when forwarding the request to the upstream endpoint. The value is one of the HTTP methods below, written as a literal value, not as an expression:
deletegetheadoptionspatchpostput
hostThe upstream origin, such as https://upstream.example.com or upstream.example.com:8080. Without a scheme, the gateway uses http. The gateway appends path and query_string to it.
pathThe upstream path.
query_stringThe upstream query string.
headersA mapping of HTTP headers to their corresponding values.
bodyThe body to be forwarded to the upstream endpoint.
timeoutThe time in milliseconds to wait for the upstream response.
defaults.timeoutconnect_timeoutThe time in milliseconds to wait for the connection to the upstream.
defaults.connect_timeoutretriesThe number of times the gateway sends a request again when the upstream sends no response. Only a request with an idempotent method is sent again. See Retries.
defaults.retriesretry_timeoutThe time in milliseconds to wait before each retry, as a non-negative integer.
defaults.retry_timeoutForward Action Object example
{
"type": "forward",
"host": "upstream.example.com",
"path": "{{request.path}}",
"query_string": "{{request.query_string}}",
"headers": "{{request.headers}}",
"body": "{{request.body}}",
"timeout": 5000,
"connect_timeout": 5000,
"retries": 2,
"retry_timeout": 1000
}Retries
When the upstream sends no response, the gateway sends the request again only if its method is idempotent (RFC 9110, section 9.2.2): get, head, options, put or delete. The gateway sends the request up to retries more times, and waits retry_timeout milliseconds before each retry. A timeout counts as no response. The gateway never sends a post or patch request again. It never retries a request that received a response, whatever its status.
Responses
The upstream status becomes the response status unless the Response Object sets status_code.
When the response body is {{action.result.body}} or {{action.error.body}}, the gateway sends the upstream bytes as it received them. The response then keeps the upstream content-type, or has none when the upstream sent none. A content-type in the Response Object headers replaces the upstream one. The gateway sends any other text body as it is. It encodes any other body in the negotiated content type.
Failures without a response
When the upstream sends no response and no retry is left, the gateway answers with an error body and does not evaluate on_error:
| Cause | Error URI | Status |
|---|---|---|
The connect or the response outlasts connect_timeout or timeout | bondy.error.gateway_timeout | 504 |
| Any other failure to reach the upstream | bondy.error.bad_gateway | 502 |
WAMP Action
An action that transforms an incoming HTTP request to a WAMP operation.
typeThe value wamp_call. For wamp_publish, see WAMP Publish Action.
procedureThe URI of the procedure to call.
optionsThe WAMP message options.
{}argsThe WAMP message args.
[]kwargsThe WAMP message kwargs.
{}timeoutThe CALL option timeout, in milliseconds, unless options sets a non-zero timeout.
defaults.timeoutretriesThe CALL option _retries, unless options sets a non-zero _retries.
defaults.retriesA wamp_call action passes its timeout as the CALL option timeout, and its retries as the CALL option _retries. A non-zero value of the same option in options takes precedence. After a timeout or the loss of the callee, the router retries the call only when the callee registered the procedure with _idempotent set to true. The action accepts no connect_timeout and no retry_timeout.
WAMP Action example
{
...
"paths": {
"/accounts" : {
"post": {
"action": {
"type": "wamp_call",
"procedure": "com.example.account",
"options": {"timeout": 15000},
"args" : ["{{request.body}}"],
"kwargs" : {}
},
"response": {,
...
}
}
}
}
}WAMP Publish Action
An action that publishes an event to a WAMP topic, with type set to wamp_publish. Its fields are those of the WAMP call action, with topic in place of procedure: topic, options, args and kwargs. It also accepts timeout, which defaults to defaults.timeout; the gateway does not pass it to the publication. It accepts no retries. Every field can be an expression evaluated against the API Context.
On success, action.result is {"publication_id": <id>}.
WAMP Publish Action example
{
"type": "wamp_publish",
"topic": "com.example.account.created",
"options": {},
"args": ["{{request.body}}"],
"kwargs": {},
"timeout": 15000
}Response Object
The response object defines what the API Gateway should respond in case of a successful result or error. The purpose of this declaration is to be able to customise the outcome of the action performed according to the Action Object declaration.
The outcome is obtained from the API Context action property by using an expression such as {{action.result.PROP}} (in case of a successful result) and {{action.error.PROP}} (in case of an error) where PROP will depend on the type of action performed.
on_resultA declaration of the desired HTTP response in case the action (as defined in the sibling action object) was successful.
on_errorA declaration of the desired HTTP response in case the action (as defined in the sibling action object) failed.
WAMP Response Object Example
{
...
"paths": {
"/accounts" : {
"post": {
"action": {
"type": "wamp_call",
...
},
"response": {,
"on_result": {
"body": "{{action.result.args |> head}}"
},
"on_error": {
"status_code": "{{status_codes |> get({{action.error.error_uri}}, 500) |> integer}}",
"body": {
"error_uri": "{{action.error.error_uri}}",
"args": "{{action.error.args}}",
"kwargs": "{{action.error.kwargs}}",
"details": "{{action.error.details}}"
}
}
}
}
}
}
}Defaults Object
The defaults object is used to define default values for the API specification objects properties.
The API Specification parser will use this object to find a default value for the following keys when evaluating the different objects:
schemesAn array of strings where values can be: http or https.
acceptsAn array of content types. The supported content types are:
application/jsonapplication/json; charset=utf-8application/msgpackapplication/msgpack; charset=utf-8application/x-www-form-urlencoded
["application/json", "application/msgpack"]providesAn array of content types. The supported content types are:
application/jsonapplication/json; charset=utf-8application/msgpackapplication/msgpack; charset=utf-8
["application/json", "application/msgpack"]headersA mapping of HTTP headers to their corresponding values.
{}security{}body_max_bytesbody_read_bytesbody_read_secondstimeoutThe default timeout of a forward, wamp_call or wamp_publish action, in milliseconds.
60000connect_timeoutThe default connect_timeout of a forward action, in milliseconds.
8000retriesThe default retries of a forward or wamp_call action.
0retry_timeoutThe default retry_timeout of a forward action, in milliseconds.
5000Security Object
The Security Object defines how requests to an API version authenticate. The router enforces three of the schemes the parser accepts:
type | Requests to the version's paths | Routes Bondy adds under the version's base_path |
|---|---|---|
| (empty object) | Served without authentication. | None. |
oauth2 | Require a valid Bondy OAuth2 access token. | The token and revoke paths, /oauth/jwks, and a verify route. |
oidc | Require the realm's OIDC ticket cookie, bondy_ticket_<realm_uri>. A request other than GET, HEAD or OPTIONS must also send the value of the bondy_csrf_<realm_uri> cookie in x-csrf-token. | /oidc/login, /oidc/<provider>/callback, /oidc/logout, and a verify route. See OIDC Authentication. |
basic | Refused. | None. |
api_key | Refused. | None. |
Each scheme accepts only the keys listed for it below. The parser refuses any other key, including scopes: the gateway checks no OAuth2 scope.
basic and api_key do not protect a path
A specification using one of these schemes loads, but Bondy refuses every request to the version's own paths. It never serves them without authentication. Use oauth2 or oidc to protect an HTTP API.
An oidc path authenticates the cookie the way a WAMP session opened with it authenticates: the realm's authmethods must include cookie, the ticket's scope must cover the realm, and its issuer must be trusted by the realm. A ticket issued for an identity Bondy does not store takes its roles from the ticket.
OAuth2 Authentication
typeA value of oauth2.
schemesAn array of strings where values can be: http or https.
["http"]flowOne of the following values:
implicitauthorization_codeclient_credentialsresource_owner_password_credentials
token_pathThe relative path to use for the obtain/refresh token action.
"/oauth/token"revoke_token_pathThe relative path to use for the revoke token action.
"/oauth/revoke"verify_pathThe relative path of the verify route.
"/oauth/verify"descriptionA description of the scheme.
OIDC Authentication
typeA value of oidc.
providerThe name of the OIDC provider the login flow uses.
verify_pathThe relative path of the verify route.
"/oidc/verify"descriptionA description of the scheme.
Basic Authentication
typeA value of basic.
schemesAn array of strings where values can be: http or https.
["http"]API Key Authentication
typeA value of api_key.
schemesAn array of strings where values can be: http or https.
["http"]header_name"authorization"Verify route
The oauth2 and oidc schemes add a route that lets a reverse proxy, such as NGINX with auth_request, ask whether a request carries a valid Bondy credential. It is mounted at <base_path>/oauth/verify for oauth2 and <base_path>/oidc/verify for oidc; set verify_path in the Security Object to change it. It verifies against the realm the specification is bound to.
The route accepts GET and HEAD. It reads the credential from the first of these that is present, and does not fall back to a later one if that credential fails:
Authorization: Bearer <credential>X-Bondy-Ticket: <ticket>- The
bondy_ticket_<realm_uri>cookie set by the OIDC login flow
It checks the credential's signature, expiry and revocation; that its scope covers the realm and its issuer is trusted by the realm; that the user is enabled and still exists; and that the realm still allows connections. A credential issued by the OIDC login flow for an identity Bondy does not store locally passes without a local user.
| Outcome | Status | Response |
|---|---|---|
| Valid credential | 200 | A JSON body with active, authid, authrealm, realm, authroles, authmethod, scope, issued_at, expires_at and expires_in, and the headers x-bondy-authid, x-bondy-authrealm, x-bondy-realm, x-bondy-authroles (comma-separated), x-bondy-authmethod and x-bondy-expires-at. |
| Anything else | 401 | A JSON error body with active: false. |
Every failure answers 401, including server-side ones, because NGINX turns any other non-2xx status from auth_request into a 500. The route answers who the caller is, not what they may do.
Loading Specifications at Startup
Specifications are usually loaded at runtime through the HTTP API. A node can also load them from a file on every boot.
The path of a JSON file holding one specification object or an array of them. When the key is unset, no file is loaded.
Each node reads the file on every boot, before its listeners start, and stores each valid specification in the replicated store, from where it reaches the other nodes. A specification identical to the stored one is not written again, so an unchanged file produces no replicated writes on reboot.
The file only adds and updates specifications. Removing a specification from the file does not delete it from the store; delete it with the bondy.http_gateway.api.delete WAMP procedure.
Bondy validates every specification in the file before it stores any of them:
- A missing file logs a warning, and the boot continues.
- A file that is not valid JSON logs an error. Nothing from it is loaded, and the node does not boot.
- A specification that fails validation logs an error. No specification from the file is loaded, and the node does not boot.
Default Values
Status Codes
Every error URI in Bondy's catalogue has a default HTTP status, listed in the HTTP column of the Error Reference. When a wamp_call or wamp_publish action fails and the on_error response sets no status_code, the gateway answers with the default status of the error URI. For a URI that is not in the catalogue, including an application's own error URI, the default status is 500.
Bondy also initialises the API Context status_codes map from the catalogue. The specification's status_codes key overrides or extends that map, at the API level and again at the version level. The map changes a response status only through an expression that reads it, such as {{status_codes |> get({{action.error.error_uri}}, 500) |> integer}} in on_error.status_code:
{
"status_codes": {
"com.example.error.not_found": 404,
"bondy.error.timeout": 503
}
}