How To Create A Node.js Microservice For Your Ionic App

In my previous post I created an Ionic 2 app that reads the posts from a Facebook Page and displays them in the app. I also mentioned that hard coding the Access Token for the Facebook Graph API within the app wasn't ideal, since it can be stolen by anyone who decompiles your app.

In this post we'll create a very simple Node.js service that will handle the call to the Facebook Graph API for us, so we don't need to include the Access Token in our Ionic app anymore.

Node.js and microservices

Node.js is a JavaScript runtime which you can use on a server to run JavaScript code. This enables frontend developers to create web services using JavaScript.

There are a couple of different frameworks built on top of Node.js that you can use to create web services, the most popular one being Express.

However, I recently stumbled upon this excellent post about building microservices with Node.js using micro, a lightweight library that's very easy to use.

A microservice is a service that does just one thing and can be deployed independently from other (micro)services.

I thought it was a perfect fit for the service I wanted to create in this tutorial. So, enough background information, let's code!

Setup service

We'll start by creating a directory for our service and creating a package.json file in it.

$ mkdir nodejs-tutorial-micro
$ cd nodejs-tutorial-micro
$ npm init -y

That last command will create a package.json file for us with some default values, you can leave out the -y and it will then guide you through setting up the package.json.

Install dependencies

Next, we'll install the micro package and the request package. This last one we'll use to do the request to the Facebook Graph API.

$ npm install micro request --save

Configure package.json

In the scripts section add this line "start": "micro" so we can use npm start later to fire up our service.

Your package.json file should now look like this:

{
  "name": "nodejs-tutorial-micro",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "micro",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "micro": "^7.0.6",
    "request": "^2.79.0"
  }
}

Create index.js

As you can see in the package.json, our main entry point for the service is index.js, so let's go ahead and create that file. We can write our code in ES6 (ES2015) because it's supported by Node.js. If you want to use TypeScript, you'll have to set up the transpilation to ES6.

I'm not going to go through the details of the Facebook Graph API here, you can learn more about it in my previous tutorial.

const request = require('request');  
const url = require('url');

module.exports = function (req, res) {

    const accessToken = '<your access token>';
    const query = `?access_token=${accessToken}&date_format=U&fields=posts{from,created_time,message,attachments}`;

    const pageName = url.parse(req.url).pathname.substring(1);

    request(`https://graph.facebook.com/${pageName}${query}`).pipe(res);
}

We're using require to import the request module we installed earlier and we're also importing url which is a core Node.js module.

To create the microservice we only need to export a function that takes in a request and a response parameter.

We parse the request url with url.parse to get the name of the Facebook Page we want to query and then we use request to do the request to the Facebook Graph API and pipe the output into the response of our microservice.

So that means we're just passing through whatever we received from the Facebook API. You don't have to do it that way, you can also do some processing on the response from Facebook before you make your own response to send back to the client.

Well, that's it, our service is ready, let's test it!

$ npm start

This command will fire up our service on http://localhost:3000/. So if you go to your browser now and type in http://localhost:3000/unsplash, you should receive the JSON data from the Facebook Page.

You can also use curl on the command line to test the service.

$ curl http://localhost:3000/unsplash

Or use httpie for a better experience on the command line. :)

Modify Ionic app

So now we have our service working, let's modify our Ionic app to call our own service instead of the Facebook API and remove the Access Token.

import { Http } from '@angular/http';  
import { Injectable } from '@angular/core';

import { Observable } from 'rxjs/Rx';  
import 'rxjs/add/operator/map';

@Injectable()
export class FacebookService {

  constructor(private http: Http) { }

  getPosts(pageName: string): Observable<any[]> {
    const url = `http://localhost:3000/${pageName}`;

    return this.http
        .get(url)
        .map(response => response.json().posts.data);
   }
}

And now we're done, test the app in the browser with the command below. Make sure your service is up and running.

$ ionic serve --lab 

Error handling and configuration

I've kept the service very simple, but you should obviously take into consideration how you want to handle errors.

micro handles errors for you by returning a 500 status code, if you want different behavior you can override that. You can find more information on error handling on the github page.

If you want to use a different port than the default 3000, you can change npm start to use micro -p <portnumber> in package.json.

Deploying service to server

Now that you have your own microservice, you'll need a server to deploy it on.

I personally use Digital Ocean, it's also what this blog is hosted on. You can get your own private server starting at $5 a month and get $10 credit if you sign up with this link.

One of the things I like about Digital Ocean, is that they have an amazing collection of tutorials on how to set up your server. This one is especially useful for deploying your microservice: How To Set Up a Node.js Application for Production on Ubuntu 16.04.

Have fun creating your own microservices and let me know in the comments if you have any questions.