Development Advanced Topics
Starting with DeltaSync handling, this section will grow to contain all advanced topics regarding generated services.
DeltaSync (>= ApiOmat 20.03.1)
DeltaSync allows you to reduce the payload of responses that would contain multiple entities.
It can be applied to GET requests that return collections of a specific model (e.g. getAllModels or getReferences) and is controlled via the request headers. You can find more information about the underlying concept on the DeltaSync page.
DeltaSync is available since ApiOmat 20.03.1 (with Brewer 1.1.0).
This section explains how you can use DeltaSync in your generated service.
Implementation
You can use the following classes to implement the DeltaSync handling:
DeltaSyncRequestWrapper
The DeltaSyncRequestWrapper is an adapter class that wraps the HttpServletRequest and provides a convenient way to access DeltaSync headers of the request over its getter getDeltaSyncMap.
You'll get a Map with all DeltaSync headers that are contained in the request. The key is the header name and the value should be a String in JSON format.
RequestState
The RequestState is an automatically created, request scoped bean from our brewer-base library. It allows you to control the behavior for requests to the YAMBAS backend.
You can configure deltaSyncHandledByService, which indicates whether the service or YAMBAS handles the DeltaSync headers. The default value is false, which means that YAMBAS is handling DeltaSync.
ReponseState
The ResponseState is an automatically created, request scoped bean from our brewer-base library. It allows you to control the response of your service.
It holds a Map of DeltaSync headers which are merged with the headers added in the controller. To add headers to the Map, you can use the following methods:
-
addDeletionDeltaSyncHeader (set the x-apiomat-delta-deleted header with the IDs of deleted objects)
-
addRemovedDeltaSyncHeader (set the x-apiomat-delta-removed header with the IDs of removed objects)
These methods each take the DeltaSync header values as a parameter (e.g. the IDs of all models deleted since the last synchronization), convert them to an appropriate JSON String and set the pair of header key and header value to the DeltaSync Map.
Alternatively, you can construct the map of headers yourself and set it in the ResponseState bean with setHeaders.
For more details, please refer to the javadoc.
Usage (code examples)
In the <ModelClass>ApiServiceImpl component of your service, you can simply inject the following beans and make use of them as shown in the loadAll method.
@Autowired
private
HttpServletRequest request;
@Autowired
private
ResponseState responseState;
@Autowired
private
RequestState requestState;
//...
@Override
public
List<ModelClass> loadAll(
final
String appName,
final
String q,
final
boolean
withClassnameFilter,
final
boolean
withReferencedHrefs )
{
/* Set handling of DeltaSync as a task of the service */
this
.requestState.setDeltaSyncHandledByService(
true
);
final
List<ModelClass> result =
super
.loadAll( appName, q, withClassnameFilter, withReferencedHrefs );
/* Wrap request so DeltaSync headers can be extracted */
final
DeltaSyncRequestWrapper req =
new
DeltaSyncRequestWrapper(
this
.request );
/* Extract DeltaSync headers from request */
final
String deltaSyncValue = req.getDeltaSyncHeaderValue( );
/* Implement DeltaSync handling */
if
( deltaSyncValue !=
null
)
{
final
Long lastSync = Long.parseLong( deltaSyncValue );
result.removeIf( e -> ( e.getLastModifiedAt( ).toEpochMilli( ) < lastSync ) );
}
/* Calculate deleted IDs and set as header value to response */
List<String> deletedIds =
new
ArrayList<String>();
/* Do calculation logic here ... */
this
.responseState.addDeletionDeltaSyncHeader(deletedIds);
return
result;
}
Once you have implemented DeltaSync handling, you can test the behaviour by sending requests to your service that include DeltaSync headers. Timestamps (used in the DeltaSync header value) need to be Unix epoch time in milliseconds (thus a Long variable).
Example:
curl -i -X GET
"${hostAddress}/yambas/rest/apps/${yourAppName}/models/${yourServiceName}/v/${yourServiceVersion}/${modelName}?hrefs=false&withClassnameFilter=true&withReferencedHrefs=false"
--header
"X-apiomat-delta: ${timestamp}"
--header
"Accept: application/json"
--header
"X-apiomat-system: ${system}"
--header
"X-apiomat-sdkVersion: ${sdkVersion}"
--header
"X-apiomat-apikey: ${yourApiKey}"
--header
"Authorization: ${auth}"
--header
"X-apiomat-appname: ${yourAppName}"
Custom Headers in Requests to Yambas (>= ApiOmat 20.11.0)
You can use the request-scoped RequestState object to set additional headers for the requests to Yambas over a FeignClient. The RequestState provides methods to append custom headers. Please note that existing headers will be overwritten by your custom headers. If you need to append an header value, you have to append it manually. Alternatively, you can extend the class RequestHeaderRequestInterceptor and overwrite the addCustomHeaders method with your own implementation to change this behavior. Don't forget to configure this custom implementation in your application.yml.
CORS handling (>= ApiOmat 20.11.0)
This section explains how to configure Cross Origin Resource Sharing in your service - in other words, whether external pages can make cross domain requests to YAMBAS via your service.
CORS handling is available since ApiOmat 20.11.0 (with Brewer 2.0.0).
You can configure CORS handling via the following properties of your service (in src/main/resources/application.yml ):
-
{ServiceName}.cors-configuration.allowedOrigins: Set the allowed origins (URIs).
-
{ServiceName}.cors-configuration.allowedMethods: Set the allowed HTTP methods.
The default value for both properties is *, which means all origins and methods will be allowed as long as they are valid URIs/HTTP methods, respectively.
If either property is set to "none", or has an empty value, no CORS requests will be allowed at all!
Here is an example where CORS is enabled only for GET and HEAD requests from two specific URIs:
hobbitservice:
cors-configuration:
allowedOrigins:
- "http://127.0.0.1:9081"
- "https://other.secure.domain"
allowedMethods:
- GET
- HEAD
When you start your service, the configuration class {ServiceName}CorsConfiguration will register all of your service's data model endpoints for CORS.
As part of this process, it retrieves the values for both properties and uses them as params for the registerMapping method of the Spring class CorsRegistry.
If you have created your own custom endpoints and need to enable CORS for them, simply add them to the list of endpoints in the addCorsMappings method of {ServiceName}CorsConfiguration.
For example:
@Override
public
void
addCorsMappings(
final
CorsRegistry registry )
{
final
String[ ] endpoints =
{
/* Regular data model endpoints */
"/apps/{appName}/models/HobbitService/**"
,
"/apps/{appName}/data/files/HobbitService/**"
,
"/apps/{appName}/data/images/HobbitService/**"
,
/* Custom endpoints */
"/apps/{appName}/custom/HobbitService/**"
,
"/apps/{appName}/admin/HobbitService/secret"
};
/* Register endpoints ... */
}
Add logo for marketplace
You can add a SVG or PNG image as your service's logo.
This image must be named logo.[png/svg] and placed inside the src/main/resources/ folder of your generated service.
To achieve a good result, please use a resolution of 81x81px.