Using the Liberator REST Adapter
This article explains how to enable the Liberator REST Adapter and how to configure it to forward requests on to a REST API service on behalf of the Caplin Platform. It will also cover how to make GET, POST, PUT, and DELETE REST operations from a StreamLink client.
The REST API service used in this tutorial is a demo API embedded within the REST Adapter for testing purposes.
We’ve assumed that you use the Caplin Deployment Framework to manage your installation, and that you’ve already installed the Deployment Framework and Liberator. For more information on installing the Deployment Framework and deploying Caplin components to it, see here.
Enable the Liberator REST Adapter
The Liberator REST Adapter is disabled by default when you first install Liberator. To enable it, follow the steps in Enabling the REST Adapter.
Enable the demo REST API service in the REST Adapter
The REST Adapter provides a basic demo REST API service that allows users to fetch, add, edit and delete prices (bid and ask) for currency pairs.
The demo REST API is provided for testing purposes only and should be disabled when using the REST Adapter in production. Data is held in an in-memory database and is reset each time the REST Adapter is restarted |
Add the following configuration to the REST Adapter’s datasource.conf
override file:
Follow the steps below:
-
In the REST Adapter’s
datasource.conf
override file, set the configuration below:global_config/overrides/LiberatorRESTAdapter/DataSource/etc/datasource.confrest-api-port
integerenable-demo-rest-api
truedemo-rest-api-credentials
username passwordExample 1. Enabling the demo REST API in the REST AdapterThe following configuration instructs the REST Adapter to start up the REST API service on port
8099
and authorise requests for useruser1
.rest-api-port 8099 enable-demo-rest-api true demo-rest-api-credentials user1 user1password
-
Restart the REST Adapter
-
Run the
curl
command below to test your configuration:curl --request GET \ --url http://localhost:8099/demorestapi/fxprices \ --header 'Authorization: Basic dXNlcjE6dXNlcjFwYXNzd29yZA=='
Demo REST API specification
The DEMO Rest API supports the following methods:
Retrieve all currency pairs with bid and ask prices
Method |
|
Path |
|
Headers |
|
Request Body |
none |
Example |
|
Submit a new currency pair with bid and ask prices
Method |
|
Path |
|
Headers |
|
Request Body |
|
Example |
|
Update bid and/or ask price for a currency pair
Method |
|
Path |
|
Headers |
|
Request Body |
|
Example |
|
Delete a currency pair
Method |
|
Path |
|
Headers |
|
Request Body |
none |
Example |
|
Mapping a REST endpoint to a Caplin Platform subject
In order to route Platform requests for a chosen subject to the REST API service, it is necessary to configure the REST endpoint mapping in the REST Adapter…
add-rest-mapping subject-prefix prefix base-url http://localhost:api_port/demorestapi end-rest-mapping
… and to add the subject-prefix
to Liberator’s data service configuration…
if "${RESTADAPTER_DISCOVERY_ENABLED}" == "" add-data-service service-name LiberatorRESTAdapter${THIS_LEG} service-type rest include-pattern prefix … end-data-service else add-data-service service-name LiberatorRESTAdapter service-type rest include-pattern prefix … end-data-service endif
The following configuration will instruct the REST Adapter to route all requests on the /DEMORESTAPI
subject to the demo REST API. Note that the port used in the url is the same as that configured as the rest-api-port
earlier.
add-rest-mapping subject-prefix /DEMORESTAPI/ base-url http://localhost:8099/demorestapi/ end-rest-mapping
In each add-data-service
block in the REST Adapter’s rttpd.conf
override file, add an include-pattern
option for /DEMORESTAPI
.
include-pattern ^/DEMORESTAPI
Testing your configuration
Restart the Platform and follow the steps below to test requests to the REST service through the REST Adapter using the Liberator Explorer diagnostic tool:
-
In a web browser, navigate to your Liberator’s website (for example, http://localhost:18080)
-
Click View Diagnostics > Liberator Explorer
-
Type the following subject in Liberator Explorer’s subject bar:
/DEMORESTAPI/fxprices
-
Select Snapshot from the dropdown
-
Click the Params button, add the
Authorization
header (Base64-encoded username and password), then click the Apply button -
Click the go button ( )
Making StreamLink Requests to the REST Adapter
This section covers the composition of StreamLink requests for interacting with the REST API service when building a Caplin Platform client application. We will use the StreamLink methods corresponding to GET, POST, PUT and DELETE operations.
Download this simple client UI for the demo REST API and open it in an editor of your choice. The page already includes methods to make a StreamLink connection to Liberator and display the connection status. The next few steps will demonstrate how you can wire-up the buttons on the page to fetch data from the UI, create new currency pairs, alter prices for a currency pair, and delete a currency pair.
-
If necessary, change the values for the
liberatorUrl
,username
andpassword
constants to connect to Liberator. -
Set the
subjectPrefix
constant to match thesubject-prefix
configured earlier in the REST Adapter configuration. -
The GET FX Prices button calls the
getPrices()
function to populate a table with the currency pairs and prices returned from the REST API. Use theStreamLink.snapshot()
method to make the request as follows:streamLink.snapshot( subjectPrefix + "/fxprices", subscriptionListener, { headers:[{ header:"Authorization", value:"Basic credentials" }] } );
This method requests the
/prefix/fxprices
subject, also setting the Authorization header as a parameter which will be added to the request made by the REST Adapter to the REST Service. ThesubscriptionListener
implements callback functions to:-
log the status of the subscription (
onSubscriptionStatus
) -
display data received (
onJsonUpdate
) -
display a subscription error (
onSubscriptionError
)
-
-
Open the page in the browser and click the GET FX Prices button. You should notice that the subscription status messages are output in the browser’s console and ultimately a table is created containing the data received from the REST service.
-
At this point it is worth taking a look at the REST Adapter log in
<Framework-root>/kits/LiberatorRESTAdapter/DataSource/var/event-RESTAdapter.log
which shows the following events taking place behind the scenes.Example 3. REST Adapter log messages following an example request for /DEMORESTAPI/fxpricesSome configuration changes may be required to the LiberatorRESTAdapter blade to output all the log lines shown below. Try setting log-level FINER
andlog-use-parent-handlers TRUE
.-
Liberator opens a JSON Channel and sends in a JSON message containing the request details i.e. the REST verb (
GET
), the path (/DEMORESTAPI/fxprices
) and the parameters (headers
).INFO: Opening RestRequestChannel com.caplin.datasource.internal.channel.JsonChannelImpl@44f26d3a … FINER: In: Peer 0 UpdatePacket [subject=/DEMORESTAPI/fxprices/0x29L667rLHU0Z6JMCWL4L/admin-0, type=JSON, fields=[={ "verb":"GET", "path":"/DEMORESTAPI/fxprices", "headers":[{"header":"Authorization", "value":"Basic dXNlcjE6dXNlcjFwYXNzd29yZA=="}] }], flags=5168, seqnum=8] … INFO: Received message JSON, Subject=</DEMORESTAPI/fxprices/0x29L667rLHU0Z6JMCWL4L/admin-0>, Image=true, Json=<{ "verb":"GET", "path":"/DEMORESTAPI/fxprices", "headers":[{"header":"Authorization", "value":"Basic dXNlcjE6dXNlcjFwYXNzd29yZA=="}] }>, jsonTree=<{"verb":"GET","path":"/DEMORESTAPI/fxprices","headers":[{"header":"Authorization","value":"Basic dXNlcjE6dXNlcjFwYXNzd29yZA=="}]}> on RestRequestChannel JSON, Subject=</DEMORESTAPI/fxprices/0x29L667rLHU0Z6JMCWL4L/admin-0>, Image=true, Json=<{ "verb":"GET", "path":"/DEMORESTAPI/fxprices", "headers":[{"header":"Authorization", "value":"Basic dXNlcjE6dXNlcjFwYXNzd29yZA=="}] }>, jsonTree=<{"verb":"GET","path":"/DEMORESTAPI/fxprices","headers":[{"header":"Authorization","value":"Basic dXNlcjE6dXNlcjFwYXNzd29yZA=="}]}>
-
The REST Adapter matches the path to a REST endpoint mapping in its configuration based on the path’s prefix (
/DEMORESTAPI
maps to the urlhttp://localhost:8099/demorestapi/
).FINER: Mapping "/DEMORESTAPI/" found for subject "/DEMORESTAPI/fxprices".
-
The GET request is made using the request headers provided.
INFO: Submitting HTTP GET request to endpoint /DEMORESTAPI/ FINE: Configured endpoint for request : "http://localhost:8099/demorestapi/fxprices" FINE: baseURL is: http://localhost:8099/demorestapi/ INFO: Using Authorization header provided in request headers.
-
The response received is mapped to JSON. (No mapping necessary in this case as the Content-Type for the response was
application/json
.)INFO: Received response for subject /DEMORESTAPI/fxprices: Status=200 OK FINE: Response for subject /DEMORESTAPI/fxprices has Content Type=application/json FINE: Mapping json response from url http://localhost:8099/demorestapi/fxprices
-
A JSON message is sent back to Liberator on the JSON Channel which contains the HTTP response code received from the REST API service (
200
) and the payload (response body).INFO: Returning REST response for subject /DEMORESTAPI/fxprices/0x29L667rLHU0Z6JMCWL4L/admin-0 with code: "200" and body: "[{"currencyPair":"GBPUSD","bidPrice":1.2682,"askPrice":1.2681},{"currencyPair":"GBPEUR","bidPrice":1..." FINER: Out: Peer 0 UpdatePacket [subject=/DEMORESTAPI/fxprices/0x29L667rLHU0Z6JMCWL4L/admin-0, type=JSON, fields=[(0)={"code":"200","payload":[{"currencyPair":"GBPUSD","bidPrice":1.2682,"askPrice":1.2681},{"currencyPair":"GBPEUR","bidPrice":1.1557,"askPrice":1.1559},{"currencyPair":"USDCHF","bidPrice":0.877,"askPrice":0.8771},{"currencyPair":"USDJPY","bidPrice":147.699,"askPrice":147.717}]}], flags=4144, seqnum=15]
-
The JSON Channel between Liberator and the REST Adapter is closed.
INFO: Closing RestRequestChannel com.caplin.datasource.internal.channel.JsonChannelImpl@44f26d3a
-
-
The POST FX Prices button calls the
postPrice()
function to extract the values from the form and submit these to the REST API service. Use theStreamLink.create()
method to make the request as follows:streamLink.create( subjectPrefix + "/fxprices", { payload: obj, payloadType: caplin.streamlink.PayloadType.JSON, headers:[{ header:"Authorization", value:"Basic credentials" }] }, commandListener );
This time the parameters also include the payload (JSON object composed of the
currencyPair
,bidPrice
andaskPrice
extracted from the form, which will be sent to the REST Service as request body) and payload type (JSON). ThecommandListener
implements callback functions to:-
refresh the prices on screen if the
create
command succeeds by triggering thegetPrices()
function (onCommandOk
) -
display an error if the
create
command does not succeed (onCommandError
)
-
-
Use the StreamLink API to implement the calls to modify an existing currency pair prices (use
StreamLink.publish()
in theputPrice()
function) and delete an existing currency pair (useStreamLink.delete()
in thedeletePrice()
function). Each time observe the REST Adapter logs to see how the REST Adapter channels the requests to the REST API Service.
See also: