v1
Double column

Using the JavaScript client

The Northflank JavaScript client allows you to interact with Northflank via JavaScript code. The JavaScript client can be installed using either NPM or Yarn:

  • npm i @northflank/js-client, or
  • yarn add @northflank/js-client

Usage

Below is an example of basic usage: setting up the client using an API token, fetching a list of existing projects and then creating a new project.

import { ApiClient, ApiClientInMemoryContextProvider} from '@northflank/js-client';

(async () => {
  // Create context to store credentials.
  const contextProvider = new ApiClientInMemoryContextProvider();
  await contextProvider.addContext({
      name: 'test-context',
      token: '<api-token>', // Use token retrieved from Northflank web interface: Account Settings > API > Tokens > Create API token.
  });

  // Initialize API client.
  const apiClient = new ApiClient(contextProvider);

  // Retrieve list of projects and log to console.
  const projects = (await apiClient.list.projects({})).data.projects;
  console.log(projects);

  // Create a new project.
  await apiClient.create.project({
    data: { name: 'test-project', region: 'europe-west', description: 'test project description' },
  });
})();

Calls using the JavaScript client take a combination of 3 parameters:

  • body - a payload or resource definition, usually used when creating a resource,
  • parameters - equivalent to path parameters on the API, and
  • options - equivalent to query parameters on the API

Have a look at operations such as update service deployment, list builds, and view secret for examples of the different options. You may need to switch to the 'JS client' tab on the right-hand side.

Throwing errors on request failure

The ApiClient constructor also takes an optional second boolean argument, which if set to true will cause the client to throw an error if the request is met with a HTTP error code response.

Responses

Responses are in JSON. The response object contains the following keys:

KeyDetailsNote
dataThe data returned as a result of your query
paginationIf the response is paginated, details such as current page and cursoroptional
rawResponseThe raw Response object
requestDetails of the request that you sent including url, method, headers, and body
errorIf your query results in an error, this object will include the error details status, message, and optionally id and detailsoptional

Forwarding

The JavaScript client provides functionality which allows opening port forwarding tunnels programmatically. This makes it possible to temporarily connect to private services and addons from anywhere.

The JS client exposes the forwarding module, which is responsible for handling port forwarding functionality. It provides three different methods to make use of port forwarding:

  • apiClient.forwarding.forwardService({ projectId, serviceId }): forwards ports of the specified service
  • apiClient.forwarding.forwardAddon({ projectId, addonId }): forwards ports of the specified addon
  • apiClient.forwarding.forwardProject({ projectId }): forwards ports of all services and addons in the specified project

All three methods return an array of objects providing connection details of the forwarded resource(s). The format is shown below:

type PortForwardingResult = {
  data?: {
    type: 'addon' | 'service';
    projectId: string;
    id: string;
    address: string;
    port: number;
    portName?: string;
    protocol?: 'HTTP' | 'TCP' | 'UDP';
    hostnames: string[];
  };
  error?: {
    message: string;
  };
};

When the connection is no longer needed, using apiClient.forwarding.stop() will close all port tunnels. If you need to close a specific tunnel, you can use one of the following options:

  • apiClient.forwarding.stopServiceForwarding({ serviceId, projectId })
  • apiClient.forwarding.stopAddonForwarding({ addonId, projectId })
  • apiClient.forwarding.stopProjectForwarding({ projectId })

Alternatively, the JS client also provides methods which handle closing the connection automatically by providing the handler function as an argument:

apiClient.forwarding.withServiceForwarding({ serviceId, projectId }, async (forwardingInfo) => {
  // Do something with connection details
  console.log(forwardingInfo)
});

You can also use

  • apiClient.forwarding.withAddonForwarding() and
  • apiClient.forwarding.withProjectForwarding()

Including hostnames

By default, a forwarded resource will provide an IP address that you can use to connect to it. If you also require the resources DNS hostname (the same that will be available in the Northflank UI) to use for the connection, the JS client supports this by writing to your hosts file.

For this to work, your code needs to be run with root/admin privileges and the ipOnly flag needs to be set to false when calling the forward method, for example:

  • apiClient.forwarding.forwardService({ projectId, serviceId }, false) or
  • apiClient.forwarding.withServiceForwarding({ serviceId, projectId }, async (forwardingInfo) => { ... }, false)

Example

This code snippet gives a basic example of forwarding and connecting to a MySQL addon, performing a query, and then closing the tunnel:

const forwardingInfo = await apiClient.forwarding.forwardAddon({
  projectId,
  addonId
});

const connectionConfig = {
  port: forwardingInfo[0].data?.port,
  host: forwardingInfo[0].data?.address,
  user: process.env.USERNAME,
  password: process.env.PASSWORD,
  database: process.env.DATABASE,
};

const connection = await mysql.createConnection(connectionConfig);

await connection.connect();

const results = await connection.query("SHOW TABLES;");

await connection.end();

await apiClient.forwarding.stop();

© 2022 Northflank Ltd. All rights reserved.