The Round Trip Problem
Consider a new feature added to the Product API version 1.1.0. For example, version 1.1.0 may add a property guaranteeType
to the product, createProduct, and updateProduct schemas.
Thus, the corresponding Product, CreateProduct and UpdateProduct classes in the SDK for API version 1.1.0 will also define guaranteeType.
Apiture Digital Banking APIs account for clients that are still using the older SDK for Product API 1.0.0, even though the
API is now running 1.1.0.
The TypeScript SDK for the Product API 1.0.0 includes TypeScript classes for 1.0.0 which do not include guaranteeType.
If the client receives an product response
or is passed a JSON representation of a product instance, it will contain the new property:
{
"_profile": "https://api.apiture.com/schemas/products/product/v1.1.0/profile.json",
"guaranteeType": "fdic",
"..." : " ... other properties ..."
}
When the client (via the SDK) marshals that JSON into a Product 1.0.0 object,
the guaranteeType property is dropped because the Product class has has no such property.
The same would happen in other client programming languages, such as a class named Product in a Java SDK.
If the client modifies the representation, then submits a PUT request, the reverse object mapping occurs: the client
must convert the UpdateProduct object to JSON. However, when using SDK 1.0.0,
the UpdateProduct class and schema will not contain
guaranteeType property. Without version information in the request, a PUT update will change the persisted value of the guaranteeType
property for that product instance from "fdic" to null. (This is the defined behavior of
PUT operations: PUT is always a complete
replacement of the resource representation.) In the absence of any version information in the request,
if guaranteeType is not present in the request, the server would not know the difference
between an older 1.0.0 client invoking the PUT
and a 1.1.0 client attempting to remove the value of guaranteeType;
it would change the persistent value of guaranteeType to null.
This is the Round Trip Problem with GET and PUT.
This round trip problem only occurs for clients which map JSON to strongly typed objects (programming languages objects,
not JSON objects), manipulate the objects, and then map objects back to JSON. Round tripping is not an issue when
clients operate on JSON objects directly instead of marshaling the JSON into and out of native objects. In this case,
the guaranteeType property remains in the client’s JSON object and is returned in the PUT request body, even though the
client is unaware of it.
PATCH operations do not have
this round trip problem, as values that are omitted from the PATCH request body are
ignored and do not change the value on the server.
That is, the behavior of PATCH works whether guaranteeType was intentionally omitted in the request body, or because
the 1.0.0 SDK does not have a corresponding property.
To solve this when using the SDK or marshaling, the Apiture Digital Banking API SDK does the following two operations:
- The SDK injects the correct
_profilein the representation. The_profileURL includes to the resource version associated with API version for that SDK - i.e. it identifies theProductinstance version as 1.0.0. If_profilewas omitted, the resource would is interpreted as version 1.1.0 of the Product schema, and thePUTrequest would clear out the value ofguaranteeTyperather than leave it unmodified. The SDK constructs the new request body with an accurate_profilevalue associated with the SDK version, and thus it does not round-trip the_profilein the input. - The SDK for Product 1.0.0 passes the
Apiture-Version: 1.0.0header in the request. - The SDK passes the API key request header; this value is also a surrogate for the
Apiture-Version.
If a client does not use the SDK, it should account for the round trip problem in the same way: include the _profile
that reflects the expected version number of the resource, and pass the correct Apiture-Version header corresponding
to the schema version associated with the resource and the client’s API key.