Extensions to OpenAPI

OpenAPI v3.0 provides only rudimentary support for defining links between documents. Specifically you can define a forward-pointing link which can extract values from the origin operation (e.g. from the request querystring, or response body) and pass them as request parameters to the destination operation.

For Apigraph we want to be able to completely specify the dependency relationship between API endpoints, across multiple interconnected APIs. Additionally, and importantly, we want to be able to take a leaf in the graph and trace back up its branches to the root request(s). In other words to extract all the prerequisites for any request.

For our use case we encountered three problems with OpenAPI 3.0 Links specification, which we have addressed by defining extension properties, as allowed by the OpenAPI spec. The issues that we ran into are:

  1. There is no way to use extracted values in the destination operation’s request body, except as the whole requestBody. For example you cannot take a value from the response body and use it as a field in the request body of the downstream request. This is due to limitations in the definition of request parameters - they can only address locations like the querystring or headers. We are not the first to notice this problem, there is an open issue here where we have proposed our extension format.

  2. The current forward-pointing link structure means that origin operations need to know of, and specify, all of their downstream dependents. Realistically that is only suited to the same-document use case. If you imagine the scenario of an organisation using microservices, where each service is managed by a different team, then you will find it inconvenient to define links in this way. It means you have to rely on a different team to specify your dependency requirement in the OpenAPI doc they are responsible for. In the case where your API has a dependency on a 3rd-party API then it becomes impossible. Instead we propose an alternative backward-pointing link specification (“backlinks”) that allows downstream services to fully specify their upstream dependencies.

  3. There can be multiple paths through the graph, i.e. multiple links or backlinks pointing to any one Operation. We would like a way to distinguish these paths so that Apigraph can select a particular unique path through the graph. Since “path” already has a meaning in OpenAPI we will call these paths “chains” (as in links-in-a-chain). Below we propose extensions which allow links and require backlinks to specify a named chain-id which they belong to.

x-apigraph-requestBodyParameters

This is an extension to the Link Object.

Field Name

Type

Description

x-apigraph-requestBodyParameters

Map[{JSON Pointer}, {expression}]

The keys are JSON Pointers identifying locations in the target request body. The values are runtime expressions to extract values from the source Operation. x-apigraph-requestBodyParameters is mutually exclusive of requestBody.

Example

 paths:
   '/':
      get:
        responses:
          '200':
             description: ok
             links:
               submitLink:
                 operationId: postSubmit
                 x-apigraph-requestBodyParameters:
                   /foo: $response.body#/foo
   '/submit':
     post:
       operationId: postSubmit

Here we have an operation GET / and its 200 status response defines a forward-pointing link to the postSubmit operation id (POST /submit). The link itself has a name, submitLink. So far this is all basic OpenAPI 3.0 stuff.

Under the Link Object we have our extension field x-apigraph-requestBodyParameters, which here defines a single link parameter.

The key of the parameter /foo is a JSON Pointer which selects a single field location in the link target’s request body.

The value of the parameter $response.body#/foo is a runtime expression which selects a value from the link source, exactly as used elsewhere in the OpenAPI spec - the portion after the # is also a JSON Pointer, selecting the value /foo from the response body of the source request.

x-apigraph-chainId

This is an extension to the Link Object.

For Apigraph’s purposes, if the Link does not have an x-apigraph-chainId field then it belongs to the null chain-id.

Fixed Fields

Field Name

Type

Description

x-apigraph-chainId

string

The chain-id to which this Link Object belongs. If not present then the Link implicitly belongs to the null chain-id (in Apigraph we call this an “anonymous” link).

Example

 paths:
   '/':
      get:
        responses:
          '200':
             description: ok
             links:
               submitLink:
                 operationId: postSubmit
                 x-apigraph-chainId: default
   '/submit':
     post:
       operationId: postSubmit