Introduction
Below is a short example of how to implement the Vessel Routing API. This example is written for Node.js, but can easily be translated into other programming languages.
The complete API specification can be found here.
Technical Description
To use the Vessel Routing API, you will take the following steps:
- Request a JWT access token at the DTN authentication service
- Setup the WebSocket connection with re-connect logic
- Send and receive route requests
Let us explore each step.
Request a JWT access token at the DTN authentication service
The DTN services authorization follows a standard “2-legged OAuth” approach. Once you have received your client credentials from DTN (clientId + clientSecret), you can request a token by making a POST request. The Node.js example implementation is below:
// DEFINED VARIABLES
const audienceVar = "https://routing.api.shipping.dtn.com"; const clientId = "{{toBeFilledIn}}"; const clientSecret = "{{toBeFilledIn}}"; const identityUrl = "https://auth.api.shipping.dtn.com/oauth/token"; // FETCHING THE AUTHENTICATION AND AUTHORIZATION TOKEN const response = await fetch(identityUrl, { method: 'post', body: JSON.stringify({ client_id: clientId, client_secret: clientSecret, audience: audienceVar, grant_type: "client_credentials" }), headers: {'Content-Type': 'application/json'} }); const body = await response.json(); const token = body.access_token;
The (JWT) token will be provided in the return message. The token is only valid for a limited time (24 hours), after expiry you must request a new token. In order to authorize and authenticate on use the token as “Bearer token” in the header of the WebSocket connection:
"Authorization": "Bearer {ENCRYPTED TOKEN HERE}"
Setup the WebSocket connection with re-connect logic
The following code can be used to setup the WebSocket connection. The authorization token from the previous step needs to be set as header of the WebSocket connection.
It can happen that the WebSocket is terminated or expired at the side of DTN. Hence, it is important to implement a reconnect on the WebSocket ‘close’ event. Please also note that the WebSocket connection stays open and can be used to send multiple requests. There is no need to open and close a WebSocket for every route request. You can send your own ‘id’ along with the request, this ‘id’ is returned within the response so you can self-manage the asynchronous responses from DTN.
// DEFINED VARIABLES const instructedSpeedEndpoint = "wss://instructed-speed.routing.api.shipping.dtn.com/v1"; // SETUP WEBSOCKET CONNECTION AND RECONNECT LOGIC var client; var reconnect = () => { client = new WebSocket(instructedSpeedEndpoint, { headers: { Authorization: `Bearer ${token}` }}); client.on('open', () => { console.log('Connecting to websocket server, enter messages to send, enter blank line to stop.'); client.on('message', (message) => { console.log('received: %s', message); }); }); client.on('close', () => { console.log("Reconnecting"); reconnect(); }); }; reconnect();
Send and receive route requests
In this example implementation the user can submit a route request by using the Node.js command line tools. The following code is needed to submit (send) the command line text towards the WebSocket connection. The response will be visible within the console logging.
// INTERACT WITH NODE.JS COMMAND-LINE TO SUBMIT REQUESTS
const readLineInterface = readline.createInterface({
input: process.stdin,
output: process.stdout
}
);
readLineInterface.on("line", (answer) => {
if (answer == "") {
readLineInterface.close();
process.exit(0);
} else {
client.send(answer);
}
});
Full Node.js example
import WebSocket from 'ws'; import readline from 'readline'; import fetch from 'node-fetch'; // DEFINED VARIABLES const instructedSpeedEndpoint = "wss://instructed-speed.routing.api.shipping.dtn.com/v1"; const audienceVar = "https://routing.api.shipping.dtn.com"; const clientId = "{{toBeFilledIn}}"; const clientSecret = "{{toBeFilledIn}}"; const identityUrl = "https://auth.api.shipping.dtn.com/oauth/token"; // FETCHING THE AUTHENTICATION AND AUTHORIZATION TOKEN const response = await fetch(identityUrl, { method: 'post', body: JSON.stringify({ client_id: clientId, client_secret: clientSecret, audience: audienceVar, grant_type: "client_credentials" }), headers: {'Content-Type': 'application/json'} }); const body = await response.json(); const token = body.access_token; // SETUP WEBSOCKET CONNECTION AND RECONNECT LOGIC var client; var reconnect = () => { client = new WebSocket(instructedSpeedEndpoint, { headers: { Authorization: `Bearer ${token}` }}); client.on('open', () => { console.log('Connecting to websocket server, enter messages to send, enter blank line to stop.'); client.on('message', (message) => { console.log('received: %s', message); }); }); client.on('close', () => { console.log("Reconnecting"); reconnect(); }); }; reconnect(); // INTERACT WITH NODE.JS COMMAND-LINE TO SUBMIT REQUESTS const readLineInterface = readline.createInterface({ input: process.stdin, output: process.stdout } ); readLineInterface.on("line", (answer) => { if (answer == "") { readLineInterface.close(); process.exit(0); } else { client.send(answer); } });