API Builder

Running API Builder on Raspberry Pi Cluster using Docker Swarm – Part 2

In Part 1 of this series, I gave a quick overview of the Raspberry Pi cluster configuration and how Docker Swarm is setup. This post provides the details on how to run API Builder v4.0 on the Raspberry Pi. In future posts, I will cover how to containerize API Builder to run on Docker and deploy on a Swarm cluster.

Install Node.js

The good people at NodeSource host and maintain some Node.js binary distributions. I will leverage a command they have written to add another package repository to our Raspberry Pi (RasPi), so that I can use ‘apt install’ for the required version of Node.js for API Builder.

API Builder requires Node.js version 8, and I need to update the package repository by running the following script in a command shell on the master node RasPi.

$ curl -sL https://deb.nodesource.com/setup_8.x | sudo -E bash -

Now that I have added the NodeSource package repository, I can start the installation of Node.js!

$ sudo apt install -y nodejs

I verify the Node.js version is v8.

$ node -v

Install API Builder Command Line Interface (CLI)

Now that we have the correct version of Node.js installed, I will install API Builder CLI.

$ sudo npm install -g @axway/api-builder

Once the API Builder install is completed, I will initialize a project by running the command below.

$ api-builder init mycoolproject

Now, I can install the dependencies using npm and start API Builder!

Note, the default port is 8080 if you need add the key/value pair port: 9090 to conf/default.js in the created project. The port, along with any other value can also be provided through the environment. For more information, see this documentation.

$ cd ./mycoolproject
$ npm install
$ nam start

Once it is running, I can open the browser to https://localhost:8080/console to access the UI.

If you try to access the web UI from other then localhost, i.e. some local network IP you will get access denied error. You need to edit the default.conf and update the admin.allowedHosts list.

What about those LEDs!

If you recall from Part 1, I added an array of 8 addressable RGB LED (APA102) to the General-purpose input/output (GPIO) header on the RasPi – it’s the 40 pins on the RasPi. Now that I have API Builder running on the RasPi, next I’m going to light up some LEDs!!!

If you are interested and you want to know how code is addressing the LEDs using GPIO header feel free to leave a comment or check out this blog post.

LED Python Library

I’m going to use the Pimoroni Blinkt python library to access and address the LEDs. And, the good news is the PicoCluster OS image has the libraries already installed. If you want more info about the python libraries, check out the GitHub repository.

LED Python Script

I created a new file at the root of the API Builder project.

$ touch rgbpixel.py

I update the rgbpixel.py file with the python code below.

#!/usr/bin/env python

import sys
import time

from blinkt import set_pixel, set_clear_on_exit, show, set_brightness


def usage():
 print("Usage: {} <pixel> <r> <g> <b>".format(sys.argv[0]))
 sys.exit(1)

if len(sys.argv) != 5:
 usage()

# Exit if non integer value. int() will raise a ValueError
try:
 pixel, r, g, b = [int(x) for x in sys.argv[1:]]
except ValueError:
 usage()

# Exit if any of r, g, b are greater than 255
if max(r,g,b) > 255:
 usage()

# Exit if pixel is greater than 7 - pixel indexing starts at 0
if not -1 < pixel < 7 :
 usage()

print("Setting LED {pixel} to {r},{g},{b}".format(pixel=pixel,r=r,g=g,b=b))

set_brightness(0.1)
set_clear_on_exit(False)
set_pixel(pixel, r, g, b)
show()

The script takes 4 arguments:

  1. The pixel/LED position in the array – value can be from 0 to 7
  2. Red color value – from 0 to 255
  3. Green color value – from 0 to 255
  4. Blue color value – from 0 to 255

Testing the script, I used the following example:

$ sudo ./rgbpixel.py 0 255 0 0

NOTE: You need root access to write to the GPIO header, hence the reason I’m using the ‘sudo’ command. This will come up again with Docker.

Running the command will enable the first LED and set the color red on the master node as shown.

Great! I now have a python script that can be used to light of any of the LED in the array. Next, I will setup an API that will call rgbpixel.py script.

LED API

I created a file by running the command below from the root of the API builder project directory.

$ touch apis/pixelrgbapi.js

var APIBuilder = require('@axway/api-builder-runtime');
var cmd = require('node-cmd');


var RGBPixelAPI = APIBuilder.API.extend({
    group: 'LEDapi',
    path: '/api/led',
    method: 'GET',
    description: 'this is an api that shows how to light an LEDs on RaspPi ',
    parameters: {
        r: { description: 'red', type:'query', optional:false },
        g: { description: 'green', type:'query', optional:false },
        b: { description: 'blue', type:'query', optional:false },
        p: { description: 'pixel', type:'query', optional:false }
    },
    action: function (req, resp, next) {
        console.log(req.params);
        var red = req.params.r;
        var green = req.params.g;
        var blue = req.params.b;
        var pixel = req.params.p;

        cmd.get('sudo ./rgbpixel.py '+pixel+' '+red+' '+green+' '+blue, function(err, data, stderr){
            console.log('rgbpixel.py : ',data)
            resp.response.status(200);
            resp.send(data);
            next();
        });
    }
});
module.exports = RGBPixelAPI;

Next, I updated the project dependencies to include node-cmd module and start API Builder:

$ npm install node-cmd --save
$ npm start

Once API Builder has started, I tested the API using the CURL example below.

$ curl "https://localhost:8080/api/led?r=255&b=0&g=0&p=0"
$ curl "https://localhost:8080/api/led?r=255&b=255&g=0&p=0"
$ curl "https://localhost:8080/api/led?r=255&b=255&g=255&p=0"

If you want to disable API key checks edit the conf/default.js file.

That’s all folks!

Next post, I’ll use the API Builder project created, build a Docker image, then deploy that image as a service in Docker Swarm!

Check out the other blogs in this series: