Skip to content

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:

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 is incrementally an 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 and API and the behaviour of the Gateway, that is, it also defines its implementation in terms of the actions that the Gateway need to perform.

A Future version of the API Gateway will aligning with Open API. In addition, the API Gateway implementation will be able to produce and serve an Open API specification of the APIs defined in Bondy.

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:

requestRequestObject

The 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.

securitySecurityObject

An instance of the Security Object. Its initial value comes from the API Object defaults.security or variables.security property. It is then possibly overridden recursively during evaluation by each [Path Object]#(path-object) definition.

actionobject

At runtime, it will contain the result or error of the action performed by the API Gateway during the handling of an HTTP request.

variablesmap

A 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.

defaultsmap

A 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_codesmap

A mapping of WAMP Error URIs to HTTP Status Codes, to be used when the Operation Object is a WAMP Action. The entries of this map are recursively updated during evaluation. At each level of the tree this property will merge in the values of the target object's status_codes property, so children nodes can access the entries defined in the ancestors, override them and/or add new status codes to the context.

Default: The value of the API Object defaults property.

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.

idstringIMMUTABLE

A unique tracing identifier for the request

methodstringIMMUTABLE

The HTTP method of the request. One of the following values:

  • delete
  • get
  • head
  • options
  • patch
  • post
  • put
schemearray[string]IMMUTABLE

An array of strings where values can be: http or https.

Default: ["http"]
peernamestringIMMUTABLE

A string representation of the requester IP address and port number e.g. 127.0.0.1:54678.

pathstringIMMUTABLE

The relative path of the request.

hoststringIMMUTABLE

The hostname of the request.

portstringIMMUTABLE

The port number the request.

headers() => mapIMMUTABLE

A mapping of HTTP headers to their corresponding values.

languagestringIMMUTABLE

The requested language.

Default: "en"
query_stringstringIMMUTABLE

The HTTP query string. See query_params.

query_paramsmapIMMUTABLE

A 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"}
bindingsmapIMMUTABLE

A 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"}
bodyanyIMMUTABLE

The 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_lengthintegerIMMUTABLE

The 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_idintegerIMMUTABLE

The WAMP RESULT.id.

detailsmapIMMUTABLE

The WAMP RESULT.details.

argsarray[any]IMMUTABLE

The WAMP RESULT.args.

kwargs() => mapIMMUTABLE

The WAMP RESULT.kwargs.

HTTP Forward Result

Error Object

TBD

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:

bash
curl -X "POST" "http://localhost:18081/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 StringEvaluates 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.price |> string}}"13.99"
{{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
{{defaults.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:

  1. 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.
  2. 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.

API Object

The API object is the root of an API Specification. It contains one or more API Version objects.

idstringREQUIREDIMMUTABLE

A global unique identifier for this API.

hoststringREQUIREDIMMUTABLE

A 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.

realm_uristringREQUIREDIMMUTABLE

The realm this API will target. An API can only target a single realm.

namestringIMMUTABLE

A display name for the API.

metamapIMMUTABLE

A mapping of metadata keys to values.

variablesmapIMMUTABLE

A mapping of arbitrary variable names to values or expressions. This variables can be referenced by expressions in the children objects of this object.

defaultsmapIMMUTABLE

A mapping of attributes to their default values. This values are inherited by children objects as defaults when their value is unset.

status_codesmapIMMUTABLE

A mapping of WAMP Error URIs to HTTP Status Codes. This values are inherited by children objects as defaults when their value is unset.

Default: Check the default values below.
versionsarray[VersionObject]REQUIREDIMMUTABLE

An array of Version Object instances.

API Object example
json
{
  "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" : [
    ...
  ]
}

Version Object

The Version Object represents a particular API version.

base_pathstringREQUIREDIMMUTABLE

The 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.

pathsmapREQUIREDIMMUTABLE

A 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_activebooleanIMMUTABLE

Whether the path is active.

Default: true
is_deprecatedbooleanIMMUTABLE

Whether the path is deprecated i.e. the path will be removed in future versions of the API.

Default: false
pool_sizeintegerIMMUTABLE
Default: 200
infoobject
variablesmapIMMUTABLE

A 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.

defaultsmapIMMUTABLE

A 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_codesmapIMMUTABLE

A mapping of WAMP Error URIs to HTTP Status Codes.

languagesarray[string]IMMUTABLE

An array of language code string.

Default: ["en"]
Version Object example
json
TBD

Path Object

A path specification to be used as a value to a key in the paths property of a Version Object.

summarystringIMMUTABLE

A short summary of the API.

descriptionstringIMMUTABLE

A description of the API.

variablesmapIMMUTABLE

A 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.

defaultsmapIMMUTABLE

A 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_collectionbooleanIMMUTABLE

Defines whether the resource managed in this path is a collection or not.

Default: false
headers() => mapIMMUTABLE

A mapping of HTTP headers to their corresponding values.

acceptsarray[string]IMMUTABLE

An array of content types. The supported content types are:

  • application/json
  • application/json; charset=utf-8
  • application/msgpack
  • application/msgpack; charset=utf-8
  • application/x-www-form-urlencoded
providesarray[string]IMMUTABLE

An array of content types. The supported content types are:

  • application/json
  • application/json; charset=utf-8
  • application/msgpack
  • application/msgpack; charset=utf-8
schemesarray[string]IMMUTABLE

An array of strings where values can be: http or https.

Default: ["http"]
body_max_bytesintegerIMMUTABLE
body_read_bytesintegerIMMUTABLE
body_read_secondsintegerIMMUTABLE
timeoutintegerIMMUTABLE
Default: The value defined for configuration option wamp.call_timeout (See reference).
connect_timeoutintegerIMMUTABLE
retriesintegerIMMUTABLE
retry_timeoutintegerIMMUTABLE
securitySecurityObjectIMMUTABLE
deleteOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP DELETE Request.

getOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP GET Request.

headOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP HEAD Request.

optionsOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP OPTIONS Request.

patchOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP PATCH Request.

postOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP POST Request.

putOperationObjectIMMUTABLE

The operation specification to perform in case the API Gateway receives an HTTP PUT Request.

Path Object example
json
{
    "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

actionActionObjectREQUIREDIMMUTABLE
responseResponseObjectREQUIREDIMMUTABLE
infostringIMMUTABLE
body_max_bytesintegerIMMUTABLE
Default: The parent Path Object's body_max_byte value.
body_read_bytesintegerIMMUTABLE
Default: The parent Path Object's body_read_bytes value.
body_read_secondsintegerIMMUTABLE
Default: The parent Path Object's body_read_seconds value.
Operation Object example
json
TBD

Action Object

The API Gateway currently supports 3 types of actions.

Static Action

An action that returns a static response.

typestringREQUIREDIMMUTABLE

The value static.

headers() => mapIMMUTABLE

A mapping of HTTP headers to their corresponding values.

body() => anyIMMUTABLE

The body to be returned with the response.

Action Object example
json
TBD

Forward Action

An action that forwards the incoming HTTP request to an upstream HTTP endpoint.

typestringREQUIREDIMMUTABLE

The value forward.

http_methodstringREQUIREDIMMUTABLE

The HTTP method to be used when forwarding the request to the upstream endpoint. It must be on of the HTTP methods:

  • delete
  • get
  • head
  • options
  • patch
  • post
  • put
host() => stringREQUIREDIMMUTABLE

The upstream host.

path() => stringREQUIREDIMMUTABLE

The upstream path.

query_string() => stringIMMUTABLE

The upstream query string.

headers() => mapIMMUTABLE

A mapping of HTTP headers to their corresponding values.

body() => anyIMMUTABLE

The body to be forwarded to the upstream endpoint.

timeout() => integerIMMUTABLE
Default: The parent Path Object timeout value.
connect_timeout() => integerIMMUTABLE
retries() => integerIMMUTABLE
retry_timeout() => integerIMMUTABLE
Forward Action Object example
json
TBD

WAMP Action

An action that transforms an incoming HTTP request to a WAMP operation.

typestringREQUIREDIMMUTABLE

One of the following values:

  • wamp_call
  • wamp_publish
optionsmapIMMUTABLE

The WAMP message options.

Default: {}
argsarray[() => any]IMMUTABLE

The WAMP message args.

Default: []
kwargs() => mapIMMUTABLE

The WAMP message kwargs.

Default: {}
timeout() => integerIMMUTABLE
Default: "{{defaults.timeout}}" i.e. the parent Path Object timeout value
connect_timeout() => integerIMMUTABLE
Default: "{{defaults.connected_timeout}}" i.e. the parent Path Object connected_timeout value
retries() => integerIMMUTABLE
Default: "{{defaults.retries}}" i.e. the parent Path Object retries value
retry_timeout() => integerIMMUTABLE
Default: "{{defaults.retry_timeout}}" i.e. the parent Path Object retry_timeout value
WAMP Action example
json
{
    ...
    "paths": {
        "/accounts" : {
            "post": {
                "action": {
                    "type": "wamp_call",
                    "procedure": "com.example.account",
                    "options": {"timeout": 15000},
                    "args" : ["{{request.body}}"],
                    "kwargs" : {}
                },
                "response": {,
                    ...
                }
            }
        }
    }
}

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_resultobjectREQUIRED

A declaration of the desired HTTP response in case the action (as defined in the sibling action object) was successful.

on_errorobjectREQUIRED

A declaration of the desired HTTP response in case the action (as defined in the sibling action object) failed.

WAMP Response Object Example
json
{
    ...
    "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:

schemesarray[string]IMMUTABLE

An array of strings where values can be: http or https.

Default: ["http"]
acceptsarray[string]IMMUTABLE

An array of content types. The supported content types are:

  • application/json
  • application/json; charset=utf-8
  • application/msgpack
  • application/msgpack; charset=utf-8
  • application/x-www-form-urlencoded
Default: ["application/json", "application/msgpack"]
providesarray[string]IMMUTABLE

An array of content types. The supported content types are:

  • application/json
  • application/json; charset=utf-8
  • application/msgpack
  • application/msgpack; charset=utf-8
Default: ["application/json", "application/msgpack"]
headers() => mapIMMUTABLE

A mapping of HTTP headers to their corresponding values.

Default: {}
securitySecurityObject
Default: {}
body_max_bytesintegerIMMUTABLE
Default: 25000000
body_read_bytesintegerIMMUTABLE
Default: 8000000
body_read_secondsintegerIMMUTABLE
Default: 15000
timeout() => integerIMMUTABLE
Default: "{{defaults.timeout}}" i.e. the parent Path Object timeout value
connect_timeout() => integerIMMUTABLE
Default: "{{defaults.connected_timeout}}" i.e. the parent Path Object connected_timeout value
retries() => integerIMMUTABLE
Default: "{{defaults.retries}}" i.e. the parent Path Object retries value
retry_timeout() => integerIMMUTABLE
Default: "{{defaults.retry_timeout}}" i.e. the parent Path Object retry_timeout value

Security Object

The Security Object defines the authentication method to be used for an API Version. The supported authentication methods are:

  • Basic Authentication
  • API Key
  • OAuth2
    • Client Credentials
    • Resource Owner Password

Basic Authentication

typestringREQUIREDIMMUTABLE

A value of basic.

schemesarray[string]IMMUTABLE

An array of strings where values can be: http or https.

Default: ["http"]

API Key Authentication

typestringREQUIREDIMMUTABLE

A value of api_key.

schemesarray[string]IMMUTABLE

An array of strings where values can be: http or https.

Default: ["http"]
header_namestringREQUIREDIMMUTABLE
Default: "authorization"

WARNING

CURRENTLY NOT IMPLEMENTED

OAuth2 AUthentication

typestringREQUIREDIMMUTABLE

A value of oauth2.

schemesarray[string]IMMUTABLE

An array of strings where values can be: http or https.

Default: ["http"]
flowstringREQUIREDIMMUTABLE

One of the following values:

  • implicit
  • authorization_code
  • client_credentials
  • resource_owner_password_credentials
token_pathstringIMMUTABLE

The relative path to use for the obtain/refresh token action.

Default: "/oauth/token"
revoke_token_pathstringIMMUTABLE

The relative path to use for the revoke token action.

Default: "/oauth/revoke"

Default Values

Status Codes

The following are the default values used to initialise the API Context.

json
{
    "bondy.error.already_exists": 400, // BAD REQUEST
    "bondy.error.not_found": 404, // NOT FOUND
    "bondy.error.bad_gateway": 504, // SERVICE UNAVAILABLE
    "bondy.error.http_gateway.invalid_expression": 500, // INTERNAL SERVER ERROR,
    "bondy.error.timeout": 504, // GATEWAY TIMEOUT
    "wamp.error.authorization_failed": 500, // INTERNAL SERVER ERROR,
    "wamp.error.canceled": 400, // BAD REQUEST
    "wamp.error.close_realm": 500, // INTERNAL SERVER ERROR,
    "wamp.error.disclose_me_not_allowed": 400, // BAD REQUEST
    "wamp.error.goodbye_and_out": 500, // INTERNAL SERVER ERROR,
    "wamp.error.invalid_argument": 400, // BAD REQUEST
    "wamp.error.invalid_uri": 400, // BAD REQUEST
    "wamp.error.net_failure": 502, // BAD GATEWAY
    "wamp.error.not_authorized": 403, // FORBIDDEN
    "wamp.error.no_eligible_callee": 502, // BAD GATEWAY
    "wamp.error.no_such_procedure": 501, // NOT IMPLEMENTED
    "wamp.error.no_such_realm": 502, // BAD GATEWAY
    "wamp.error.no_such_registration": 502, // BAD GATEWAY
    "wamp.error.no_such_role": 400, // BAD REQUEST
    "wamp.error.no_such_session": 500, // INTERNAL SERVER ERROR,
    "wamp.error.no_such_subscription": 502, // BAD GATEWAY
    "wamp.error.option_disallowed_disclose_me": 400, // BAD REQUEST
    "wamp.error.option_not_allowed": 400, // BAD REQUEST
    "wamp.error.procedure_already_exists": 400, // BAD REQUEST
    "wamp.error.system_shutdown": 500 // INTERNAL SERVER ERROR
}

Except where otherwise noted, content on this site is licensed under a Creative Commons Attribution-ShareAlike (CC-BY-SA) 4.0 International license.
Bondy and Leapsight are registered trademarks of Leapsight Technologies Ltd.