Accessing the Mender API with NodeJS - login version

Introduction

The Mender backend follows an API first philosphy. This means all functionality is exposed through documented endpoints, and you are invited to use those to match and implement your custom flows.

In this short tutorial, I will show you how to access the API from a NodeJS script using a login call. For more in-depth information on the API, check out the documentation and the API reference.

Prerequisites

To follow the examples you need the following:

  • a Hosted Mender account. We will use the US instance, but adapting to the EU one is straightforward. You can sign up here
  • the NodeJS runtime being installed

Tutorial

Step 0: Project setup

We will create a project named mender-api-demo using generic NodeJS practises.

mkdir mender-api-demo
cd mender-api-demo
npm init -y

For simplicity, we will use the axios library to do the API calls. Add it to the project:

npm i --save-prod axios

Now open a new file index.js in the editor of your choice, and add the line

const axios = require('axios');

to load the axios library. Then you’re ready to go!

Step 1: Authentication - logging in

NOTE: this is not possible for accounts which are using a SSO login such as Google or Microsoft, as those do not have an associated username and password!

Using your username and password, you can call the login endpoint to obtain a JWT for further interaction with the backend. Upon successful verification of your credentials, the token is directly returned. To follow this flow in NodeJS, add the following code:

axios({
  method: 'POST',
  url: "https://hosted.mender.io/api/management/v1/useradm/auth/login", 
  auth: {
    username: "your.login.name@example.com",
    password: "secret123456",
  },
  headers: {
    'Accept': 'application/json',
  }
})
.then((response) => {
  const jwt = response.data;
  console.log("received JWT: '" + jwt + "'");
  return jwt;
})
.catch((error) => {
  console.log("login error" + error);
});

This passes the token into a next .then() clause which can use it for further API calls.

The console.log call which prints the token can also be removed or commented out once you have verified correct function.

Step 2: API access

We will call the device list API endpoint to receive a list of devices accepted on our account. Please note that the endpoint is paginated, so if you have a large number of devices then the returned array will not be exhaustive.

Add the following code snippet to the .then() chain of the axios call:

.then((jwt) => {
  // Make the HTTP request using axios
  return axios({
    method: 'GET',
    url: "https://hosted.mender.io/api/management/v1/inventory/devices",
    headers: {
      'Accept': 'application/json',
      'Authorization': 'Bearer ' + jwt,
    }
  });
})
.then((response) => {
  console.log("received device list: " + JSON.stringify(response.data));
})

This prints a list including an extensive list of details on each device - the inventory - to the console.

Congratulations, you have just successfully called the Mender server API!

Next steps and conclusion

You are now perfectly equipped to start using the Mender API for your custom logic. Some ideas to explore:

  • uploading artifacts
  • creating deployments
  • gathering statistics

By exposing and documenting all facets of the API, the Mender backend offers both high customizability and anti-lock in, as you can replace each part as needed. Web frontend, backend, none or both.

What did you build? Let us know in the comments!