Appearance
Example Code
Node.js
Following is a brief example to set up a websocket connection in order to receive updates from the coldwave backend. Brief means, in order to highlight certain functions, some error checks and handlers have been omitted. By default, a more robust promise and error handling should be used.
INFO
A full example with more info can be found on (GitHub)[https://github.com/io-coldwave/coldwave-example-nodejs]
Details
The loose error handling is only employed to not unnecessarily bloat this simple example
config.ts
Configure the required parameters here
typescript
//filename: config.ts
export const USER = "<<USERNAME>>";
export const PASSWORD = "<<PASSWORD>>";
export const URL = "<<URL>>";
fetch.ts
Quick wrapper function to add a token to the fetch request and the function that generates the websocket ticket.
typescript
//filename: fetch.ts
import fetch, {RequestInfo, RequestInit, Response} from "node-fetch";
import {getToken} from "./token";
import {extractObject} from "./utils";
import {URL} from "./config";
export async function fetchWithToken(input: RequestInfo | URL, init?: RequestInit): Promise<Response> {
const _init = init || {};
const token = await getToken();
if (token !== null) {
_init.headers = Object.assign({}, {"Authorization": `Bearer ${token}`}, init?.headers);
}
return fetch(input, _init);
}
export async function getWebsocketTicket(): Promise<string | null> {
const res = await fetchWithToken(`https://${URL}/api/v1/events/ticket`);
const obj = await extractObject<{ ticket: string }>(res);
if ("ticket" in obj) {
return obj.ticket;
}
return null;
}
token.ts
The code that handles the log-in part of the application. Note that the token will expire after a period of time and this code does not handle token expiration at all.
typescript
//filename: token.ts
import fetch from "node-fetch";
import {PASSWORD, USER, URL} from "./config";
import {extractObject} from "./utils";
//The token will expire at some point
let token: string | null = null;
export async function getToken(): Promise<string | null> {
if (token !== null) return token;
const authHeader = `Basic ` + Buffer.from(USER + ":" + PASSWORD).toString("base64");
const requestOptions = {
method: "GET",
headers: {
"Authorization": authHeader
}
};
const res = await fetch(`https://${URL}/api/v1/iam/token`, requestOptions);
const parsed = await extractObject<{ token: string }>(res);
if (parsed !== null) {
token = parsed.token;
}
return token;
}
utils.ts
A small utility function to parse the response from an API call.
typescript
//filename: utils.ts
import {Response} from "node-fetch";
export async function extractObject<T extends Record<string, unknown>>(response: Response): Promise<T | null> {
if (!response.ok) {
console.log(`Response status was ${response.status} - NOT_OK`);
return null;
}
try {
const json = await response.json();
return json as T
} catch (e) {
console.error("Unable to parse json from response");
}
return null;
}
index.ts
This index file that generates a websocket ticket and then creates a new websocket connection. Events that are received via the websocket will be logged.
typescript
//https://www.npmjs.com/package/ws
import {WebSocket} from 'ws';
import {URL} from "./config";
import {getWebsocketTicket} from "./fetch";
(async () => {
const ticket = await getWebsocketTicket();
const ws = new WebSocket(`wss://${URL}/api/v1/events/${ticket}`);
ws.on('message', (data) => {
console.log('received: %s', data);
});
})()