Providing Callbacks
Callbacks describe an asynchronous request pattern where the API consumer makes a request to the API provider and includes a URL where the response should be sent. The API provider sends an immediate acknowledgement, then when the result is ready, sends it as a request to the URL the consumer supplied. The server can use the contents of the Callback and the dynamic values received during a given Operation to make the followup call back to the client (hence the name “callback”) at the URL provided.
A common use case for callbacks is to provide information on the success or failure of long-running operations that cannot be completed synchronously. An example is in the context of payments API, where payments backend systems are asynchronous and therefore cannot always return a definitive response within the typical timeout period for an HTTP request. Callbacks are therefore implemented to allow an immediate, synchronous response to be made so that payment API providers can relay the status of the payment out-of-band. A Callback object is defined as part of an Operation. It differs from a Webhook in that it is always allied to a specific Operation. Webhooks should be considered for more generic use cases as they define Path Items outside the context of a given Operation.
Our Tic Tac Toe example implements a Response object that indicates an asynchronous response to a requested move on the board. A 202 HTTP response is returned indicating the request has been accepted but the operation is not completed. The API consumer can send a URL in the HTTP header progressUrl so the API provider can send a notification when the move is complete. This header is optional, so if no value is supplied no callback will be made by the API provider:
put:
summary: Set a single board square
description: Places a mark on the board and retrieves the whole board and the winner (if any).
tags:
- Gameplay
operationId: put-square
parameters:
- name: progressUrl
in: header
description: Progress URL that should be called if asynchronous response is returned
required: false
schema:
type: string
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/mark"
responses:
"200":
description: "OK"
content:
application/json:
schema:
$ref: "#/components/schemas/status"
"202":
description: Mark operation has not completed. Callback will be used to send notification once operation is complete
This operation also describes the callback, which is implemented as a Runtime Expression that points at the progressUrl header from the parameter above. The callbacks object is defined as a Map. Each callback is defined with a name that uniquely identifies the Callback object and the runtime expression value:
callbacks:
statusCallback:
"{$request.header.progressUrl}":
post:
summary: Status of mark operation
description: Provides the status of the ongoing mark operation
operationId: markOperationCallback
requestBody:
content:
application/json:
schema:
$ref: "#/components/schemas/status"
responses:
"200":
description: Mark operation status received
The object defines or references a Path Item, qualified by the Runtime Expression. The API provider will use this Runtime Expression to resolve the value of the URL to call. The API consumer uses this object to define the implementation code for their callback API and perform activities like request payload schema validation.
The behaviors that govern when an API provider should call a callback URL are largely based on the type of operation being supported and the specifics of the implementation. We therefore do not cover such considerations in this topic.
Summary
In this topic we’ve learned that:
- Callbacks provide the means to associate a given Operation with a Callback that provides additional, out-of-band information.
- An API provider can use Callbacks to support features like long-running operations that are completed asynchronously.
- API providers can resolve a Callback URL using a Runtime Expression, which resolves to attributes of the request or response messages and allows them to call the API consumer at the resolved URL.