# Making REST requests with StreamLink

This page describes how to tunnel REST GET, POST, PUT, and DELETE operations through StreamLink to a REST endpoint, via the [Liberator REST adapter](../liberator/liberator-rest-adapter.md).

Available from: StreamLink 8

Requires: Liberator 8

## Requirements

You require:

* StreamLink 8
* A Caplin Platform stack running Liberator 8 with the LiberatorRESTAdapter blade activated and configured. For more information, see [Activating the REST Adapter](../liberator/liberator-rest-enabling.md).

## Overview

The [`StreamLink`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html) class provides four methods for interacting with REST services proxied by the Liberator REST Adapter:

| HTTP Method | StreamLink method |
| --- | --- |
| GET | [`StreamLink.snapshot`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#snapshot)(__subject__, __subscriptionListener__, __subscriptionParameters__) |
| POST | [`StreamLink.create`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#create)(__subject__, __commandParameters__, __commandListener__) |
| PUT | [`StreamLink.publish`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#publish)(__subject__, __commandParameters__, __commandListener__) |
| DELETE | [`StreamLink.delete`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#delete)(__subject__, __commandParameters__, __commandListener__) |

REST operations are packaged in RTTP format for transport to and from Liberator. An example request flow for a GET request is shown below:

**GET request**

A Liberator REST Adapter is configured to map requests to subjects beginning `/EXAMPLE/…` to a REST service’s base-URL:

**global_config/overrides/LiberatorRESTAdapter/DataSource/etc/datasource.conf**

```
add-rest-mapping
    subject-prefix  /EXAMPLE/
    base-url        https://www.example.com/api/v1/
end-rest-mapping
```

**global_config/overrides/LiberatorRESTAdapter/Liberator/etc/rttpd.conf**

```
add-data-service
    service-name     LiberatorRESTAdapter${THIS_LEG}
    service-type     rest
    include-pattern  ^/EXAMPLE/
…
```

The REST service has a collection, `news`, available at <span>https://</span>www.example.com/api/v1/news. This collection is exposed to StreamLink clients as subject `/EXAMPLE/news`.

The sequence diagram below illustrates a StreamLink client using the [`StreamLink.snapshot()`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#snapshot) method to make a GET request to the REST service’s `news` collection:

**GET request to /EXAMPLE/news**

```plantuml
hide footbox

actor Client as "StreamLink Client"

box "Caplin Platform" #LightBlue
participant Liberator
participant REST as "REST Adapter"
end box

participant Service as "REST Service"


Activate Client
note over Client
StreamLink.snapshot("/EXAMPLE/news", ...)
end note
Client -> Liberator: RTTP message

deactivate Client
Activate Liberator
Liberator -> REST: DataSource packet
Deactivate Liberator
Activate REST
note right
add-rest-mapping
    subject-prefix /EXAMPLE/
    base-url https://www.example.com/api/v1/
end-rest-mapping
end note
REST -> Service: GET https://www.example.com/api/v1/news
REST <- Service: HTTP response
Liberator <- REST: DataSource packet\n(HTTP status + payload)
Deactivate REST
Activate Liberator
Client <- Liberator: RTTP message\n(HTTP status + payload)
Deactivate Liberator
Activate Client
note over Client
SubscriptionListener.onJsonUpdate()
end note

```

## Getting started

StreamLink’s REST methods require a [`StreamLink`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html) instance with a registered [`JSONHandler`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/JsonHandler.html) instance.

The example code below creates a [`JSONHandler`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/JsonHandler.html) that uses the [Fast JSON Patch](https://www.npmjs.com/package/fast-json-patch) and [Immer](https://www.npmjs.com/package/immer)  libraries:

```js
var jsonHandler = {
    parse: function (jsonString) {
        return JSON.parse(jsonString);
    },
    patch: function (existingObject, jsonPatchString) {
        var patch = JSON.parse(jsonPatchString);
        var result = immer.produce(existingObject,
            function (existing) {
                return patch.reduce(jsonpatch.applyReducer, existing);
            });
        return result;
    },
    format: function(obj) {
        return JSON.stringify(obj, null, "\t");
    }
};

```

Pass the [`JSONHandler`](++https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/JsonHandler.html++) instance to [`StreamLinkFactory.create`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLinkFactory.html#create) to create an instance of `StreamLink` with a registered JSON handler:

```js
var streamLink = caplin.streamlink.StreamLinkFactory.create({
    username: "admin",
    password: "admin",
    liberator_urls: "rttp://localhost:18080",
    json_handler: jsonHandler
});
streamLink.connect();
```

## GET requests

Use [`StreamLink.snapshot`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#snapshot) to send a GET request.

**Example GET request**

```js
let subscriptionListener = {
    onJsonUpdate(subscription, evt) {
        console.log(evt);
    },
    onSubscriptionError(subscription, evt) {
    },
    onSubscriptionStatus(subscription, evt) {
    }
};
streamLink.snapshot("/EXAMPLE/news", subscriptionListener);
```

The [`SubscriptionListener.onJsonUpdate`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/SubscriptionListener.html#onJsonUpdate) method passes in a [`JsonEvent`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/JsonEvent.html) object. To retrieve the JSON payload as a JavaScript object, call [`JsonEvent.getJSON()`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/JsonEvent.html#getJson). 

If the REST method accepts parameters, append them to the subject as a querystring:

```js
streamLink.snapshot("/EXAMPLE/news?page=2", subscriptionListener);
```

## POST requests

Use [`StreamLink.create`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#create) to send a POST request.

**Example POST request**

```js
let commandListener = {
    onCommandError: (subject, commandErrorEvent) => {
        console.log("onCommandError", subject);
    },
    onCommandResult: (subject, commandResultEvent) => {
        console.log("onCommandResult", subject, commandResultEvent);
    }
};
let payload = {
    title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    author: "John Smith"
};
streamLink.create("/EXAMPLE/news", payload, commandListener);
```

If the response includes a payload, call `CommandResultEvent.getPayload()` to retrieve it.

## PUT requests

Use [`StreamLink.publish`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#publish) to send a PUT request.

**Example PUT request**

```js
let commandListener = {
    onCommandError: (subject, commandErrorEvent) => {
        console.log("onCommandError", subject);
    },
    onCommandResult: (subject, commandResultEvent) => {
        console.log("onCommandResult", subject, commandResultEvent);
    }
};
let payload = {
    id: "63f92d0c1a3d3",
    title: "Lorem ipsum dolor sit amet, consectetur adipiscing elit.",
    author: "George Smith"
};
streamLink.publish("/EXAMPLE/news/63f92d0c1a3d3", payload, commandListener);
```

If the response includes a payload, call `CommandResultEvent.getPayload()` to retrieve it.

## DELETE requests

Use [`StreamLink.delete`](https://docs.caplin.com/developer/api/streamlinkjs/latest/classes/StreamLink.html#delete) to send a DELETE request.

**Example DELETE request**

```js
let commandListener = {
    onCommandError: (subject, commandErrorEvent) => {
        console.log("onCommandError", subject);
    },
    onCommandResult: (subject, commandResultEvent) => {
        console.log("onCommandResult", subject, commandResultEvent);
    }
};
let payload = null;
streamLink.delete("/EXAMPLE/news/63f92d0c1a3d3", payload, commandListener);
```

If the response includes a payload, call `CommandResultEvent.getPayload()` to retrieve it.

---

**See also:**

* [Liberator REST adapter](../liberator/liberator-rest-adapter.md)
