Response Transformation
For integrations that do not conform to the OAuth 2.0 specifications for a token and refresh token exchange, an Integration DSL may specify how responses from the two exchanges can be mapped into the the platform canonical model.
Transformation is done by adding an additional property response
configuration to the request_token
and refresh_token
configuration
properties.
Transformers access properties of a response JSON using
JSONPath. Properties that do not start with $
will
be interpreted as a value, the following example demonstrates the use of both
JSONPath transformation and value mapping.
Given the response payload from an integration token request:
{
"message": "",
"code": 0,
"data": {
"access_token": "the-access-token",
"scopes": [
"foo",
"bar"
],
"merchant_id": "",
"expiry_time": "2021-07-17T20:30:00.000+00:00",
"refresh_token": "the-refresh-token"
}
}
{
"request_token": {
/* ... omitted ... */
"response": {
"access_token": "$.data.access_token",
"refresh_token": "$.data.refresh_token",
"token_type": "Bearer",
/* expires_in: "$.data.expires_in" */
"expires_at": {
"path": "$.data.expiry_time",
"date_time_format": "yyyy-MM-ddTHH:mm:ss.fffzzz"
}
}
}
The response
object defines a JSONPath expression that the platform
uses to access a value from the response, then populates the associated property
ie. $.data.access_token
maps into the IntegrationTokenResponse.AccessToken
property.
This example also demonstrates two additional features:
-
The value
Bearer
fortoken_type
maps directly into theIntegrationTokenResponse.TokenType
property with a value ofBearer
. -
expires_at
Is an object, rather than a JSONPath.
expires_in
vs expires_at
OAuth2 specifies expires_in
as a standard
field informing the client how long, in seconds, until the access_token
expires. In the example above the integration provides expires_at
. An integration
DSL may specify either expires_in
or expires_at
but not both. In the case
of the latter, expires_at
the platform will parse the date-time and compute an
expires_in
value.
Including any response transformer shifts the burden of response parsing from the standard OAuth2 parser to the author of the DSL.
Connection Context
Some third parties both send, and expect, more than an access token in the response and authenticated requests, respectively.
To accommodate this, the platform allows a response transformer to specify
a collection of properties in connection_context
. Properties defined in
connection_context
are returned along with the rest of the credentials
provided to the platform.
Values in the connection_context
can use some template expressions, like
{callback:
. This allows
an integration definition to capture values from the redirect_uri
from the
3rd party to include in the connection context.
Example
The following example parses a typical OAuth2 response with an extra top level field.
/* A response from an integration */
{
"access_token": "foo",
"refresh_token": "bar",
"token_type": "bearer",
"expires_in": 3600,
"store_id": "42"
}
/* A response transformer in the Integration Definition */
"response": {
"access_token": "$.access_token",
"refresh_token": "$.refresh_token",
"token_type": "$.token_type",
"expires_in": "$.expires_in",
"connection_context": {
"store_id": "$.store_id"
}
}
/* results in the following the platform TokenResponse */
{
"access_token": "foo",
"token_type": "bearer",
"refresh_token": "bar",
"expires_in": 3600,
"raw_payload": "{
\"access_token\":\"foo\",
\"expires_in\":\"3600\",
\"refresh_token\":\"bar\",
\"store_id\":\"42\",
\"token_type\":\"bearer\"
}",
"integration_api_code": "sample-server",
"connection_context": {
"store_id": "42"
}
}