Building Node-based APIs with the LoopBack Framework

APIs are increasingly becoming one of the most important aspects of development, no matter what platform you choose. Whether you’re building an API for public consumption or simply creating the back end for your mobile application, being able to rapidly set up and design APIs can be a great benefit for developers.

In this article, I’m going to introduce you to an open source Node.js framework built specifically for working with APIs, LoopBack. We’ll also briefly explore how easily you can use a LoopBack generated API as a back end for a NativeScript mobile application.

At a high level, LoopBack includes:

  • The ability to create REST-based APIs (obviously)
  • A simple persistence system for storing data (supporting a variety of databases, both SQL and NoSQL alike)
  • A robust security model that supports a variety of different needs
  • Built on top of Express, which means that you can re-use your Express knowledge for handling the non-API aspects of your site as well
  • Customization out the wazoo for for every aspect of development. And this is the killer thing – many tools that deliver rapid prototypes also tend to be very restricted in what they allow you to customize. LoopBack is extremely customizable!

Let’s take a look at what you need to get started.

Prereqs

As a Node.js framework built on top of Express, you can probably guess that knowing Node and Express is helpful – and it is – but you certainly do not need to be an expert. A Node.js beginner would have no problem getting started with LoopBack and, in general, you can go in without any Express knowledge at all. However, you should probably spend at least a few minutes getting familiar with the framework just so you’ve got the basics.

If you want a great introduction to both Node and Express, I recommend “Web Development with Node & Express” by Ethan Brown. This book is a great guide to getting started building web sites with Node and covers everything you can possibly imagine.

On top of basic familiarity with Node, some experience working with APIs is helpful. LoopBack is a REST-compliant API framework and REST has a few implications. That’s just a fancy way of saying that, if you know an API is REST-based, you can make a lot of assumptions about how it works. If you’re looking for a good introduction to REST that’s language agnostic, I’d strongly recommend Adam Tuttle’s “REST Assured”. This is a great book which you can finish in about an hour or so.

Finally, you’ll want to have Node installed of course. Head over to Nodejs.org and grab the right bits for your platform.

Installation

As with most things Node-related, installation will be done via npm. To get started with LoopBack, we’ll install a command line program that will handle generating applications and APIs. This command line program is optional – you could do everything by hand – but it’s going to save you a heck of a lot of time to use the CLI. In your command prompt, simply do:

npm install strongloop

StrongLoop? LoopBack was developed by a company called StrongLoop. IBM acquired StrongLoop late last year. Along with LoopBack, they also worked on other Node-related products. The CLI program still has the name of the former company. In the future, this may (probably) will change!

Once installed, you’ll have the CLI ready. I’m always confused when npm installing X gives me a program Y, and that’s the case here as well – the program you just installed is available as the slc command. You can confirm you’re good to go by running slc -v:

Testing the CLI

Starting Your Application

Now that you’ve got the CLI, you can use it to generate your first application. At the command line, type slc loopback. This will begin the process of generating a new application. You’ll be asked for a name, directory, the version to use (select 2.X) and when prompted for the kind of application, select ‘notes’ as it includes some good defaults.

Running the CLI

Once you’ve gotten past the prompts, the CLI will start downloading all the bits it needs and finish setting up your application.

The app is finished building

If you go into the folder the CLI just created, you’ll see the following folders:

  • client: This is an empty folder where you can put your client-side code for your API. You absolutely do not need to use this folder for your client-side development. Use whatever folder you want, or none at all if you’re simply building an API to be used by the public.
  • common: This will contain files related to the APIs you’ll be building in a minute.
  • node_modules: Billions of npm-related files to run the application. Ok, billions may be a bit of an exaggeration.
  • server: This is where you’ll find the LoopBack server just generated by the CLI. As stated above, this is an Express-based application so if you want to add any routes for your non-API related logic, you would do so here.

If you go ahead and fire up the server with node . you’ll see this in your command prompt:

Starting up the server

What you’re seeing here is that your app has two distinct features out of the box – a basic web server running at the root of the domain and a REST API at /explorer. If you open up the web server all you’ll see is a simple uptime notice. This is just a default route set up by the CLI that you can modify as you see fit. The explorer is where things get cool.

The Explorer

The API Explorer is basically what it sounds like – a web application that lets you test your APIs. If you want, you can go ahead and play with the Note API created as a sample, but what fun is that? Let’s build our own API.

Building an API

APIs in LoopBack are model based. What this means is that you begin by defining the ‘form’ of the data that you are working with and LoopBack does the rest.

LoopBack’s models are a collection of properties. Each property has a name, type, and different validation requirements. So, for example, if you were defining a “Cat” API, you may decide that cats have a name, breed, gender, and age. Name, breed, and gender could be strings while age would be numeric. This is completely arbitrary of course.

LoopBack models also support relationships. So you could define an ‘owner’ model that can own multiple cats and define one owner for each cat. You can get as fancy and detailed as you want.

You can also do inheritance. So if you had both a cat and dog model, you could define a generic animal model that they could both inherit from. Again, you can do that, you don’t need to do that. LoopBack supports going as complex as you want.

Enough talk – let’s actually build a cat API! Back in the command prompt, run: slc loopback:model and you will be prompted to define your model.

For the name, enter ‘cat’. For the datasource, take the default (I’ll explain that in a bit). Take the default PersistedModel for the base class as well. Say yes to exposing the model over a REST API and just hit enter for the plural (LoopBack can figure that out on it’s own). Finally, select common and then the CLI will begin asking you to define properties. To keep things simple, let’s define three properties:

  • name (string, not required)
  • breed (string, not required)
  • age (number, not required)

When it’s done, restart the server if it’s still running and reload the Explorer.

You’ll now have an entry for cat. If you expand it, you’ll see a whole suite of methods. LoopBack has defined ways for you to create, update, read (both one and many) and delete cats. You’re API is done. Seriously.

You also get a full query API against your data as well. I won’t go into that in detail in this introduction, but if you needed to find cats that were of a certain breed and younger than a particular age, the logic for that is already baked in.

To create a cat, expand the POST /cats block. On the right side will be model schema. If you click it, it will copy into the form field to the left and you can then edit the data to your liking:

Let's make a cat!

Then hit Try it out! to test the API.

We made a cat!

You’ll see a variety of things here. First, a curl command that replicates what you just did. Then the response body, code, and headers. To be clear, all the explorer did was mimic a POST operation that you can do via any client.

Now go up to GET /cats and try out the method there. You should see a JSON response of cat objects – only one in this case (although feel free to make as many cats as you want, because, more cats is more awesome). Now is a great time to ask – where in the heck is that data coming from?

LoopBack and Persistence

So where did LoopBack store that data? LoopBack has a simple ORM-like system that handles persistence for you. ORM stands for Object Relational Mapper and one of the most well known is the Hibernate framework. Basically, it is an abstraction layer between your data and how it is persisted. This means you can tell LoopBack to persist data in MySQL, or Mongo, or SQL Server, and it handles the particular commands for each system.

Out-of-the-box LoopBack includes a simple RAM-based system called an in-memory datasource. If you stop and start your demo server, the cat you made will be gone (poor cat!). The in-memory datasource is great for testing, but obviously isn’t good for production.

LoopBack calls the code it uses to persist a ‘connector’ and has officially supported versions for:

  • Cloudant
  • DB2
  • Memory
  • MongoDB
  • MySQL
  • Oracle
  • PostgreSQL
  • Redis
  • SQL Server

To use these, you first install the appropriate connector (for example: npm install --save loopback-connector-mongodb) and then define the datasource using the CLI. We won’t go any deeper into that for now, but just know that it is an easy transition from testing to ‘real’ data creation. You can also set up the in-memory connector to persist to a file. That’s handy if you are doing a lot of reloading and don’t want to have to keep entering fake data.

If you’re curious as to where all these settings are stored, let’s take a look at the file system. First, if you open the common folder, you’ll see two files related to the API you made earlier: cat.js and cat.json. The JSON file is the model definition:

{
"name": "cat",
"base": "PersistedModel",
"idInjection": true,
"options": {
    "validateUpsert": true
},
"properties": {
    "name": {
    "type": "string"
    },
    "breed": {
    "type": "string"
    },
    "age": {
    "type": "number"
    }
},
"validations": [],
"relations": {},
"acls": [],
"methods": {}
}

All the CLI did was take your input and generate an appropriate set of values from it. This means that, if you don’t like the CLI generating your files for you, then you can simply create them by hand. Or if you made a typo while entering a property, you can simply fix it here. The JavaScript file is currently (mostly) empty:

'use strict';

module.exports = function(Cat) {

};

This is where you will define any custom methods or logic. This is not something we’ll cover in the article, but if you needed a custom API for old cats, or some other logic, you would add it here. If you had weird validation (“calicos are only female”) then you could add it here as well. As I said above, LoopBack is extremely customizable and this is just a simple example of that.

If you look in the server folder you’ll see more JSON files including a datasources.json and model-config.json. The datasources file will contain information about what datasources your application uses and the model-config one helps align models to a particular datasource. As I said, we won’t bother setting up ‘real’ persistence for this demo, but that’s where you do that particular configuration.

But Wait – There’s More

As we said above, your API is literally already done. You can start building your client and run calls against the API immediately. Of course, there’s probably a few things you may want to tweak:

  • First and foremost, the API is 100% open. You can delete cats by just making a DELETE call against the API endpoint. You can lock that down in a few seconds by using the CLI and running slc loopback:acl. This will walk you through the process of defining an ACL (Access Control List) for your API that lets you define who can do what. A typical use case for this would be to lock down writes and open up reads. While LoopBack makes this simple, you can also have a completely custom security model based on whatever logic makes sense for you. Read more here: Authentication, authorization, and permissions
  • And speaking of customization – you could now add additional API methods (for example, shorthand calls to get old cats, cats of a certain breed, etc), you could modify the GET logic to add additional dynamic properties, you could add custom validation logic such that a cat of breed such and such can’t be older than a certain age. LoopBack makes this all quick and easy. Read more here: Adding application logic
  • I mentioned that LoopBack provides a ‘search’ type API along with the GET call. It also provides a count (/api/cats/count) method as well as the ability to skip rows and limit the number of results. This would allow for pagination. You can see an example of this here: Working with Pagination and LoopBack
  • And of course, you can read about everything LoopBack does at the main documentation site: http://loopback.io/doc/

The Front End

So what about that front end? For the most part, this is a non-issue. One of the benefits of using REST for your APIs is that you don’t really have to think about using it. Since you know (or can learn!) the basic conventions, actually using the API becomes a simple matter.

I’ve built an incredibly simple NativeScript application that demonstrates working with the API defined above. I won’t show all the code (mainly because I’m still pretty new to NativeScript), but you can find the entire thing by downloading the zip for this article.

First, a quick screen shot. On start up, the app calls the API and gets a list of cats. This is the rendered in a list.

List of cats

Clicking on a cat provides a detail view:

Detail for a cat

Admittedly, from an app standpoint, this is not terribly exciting, but the key here is to look at the main integration of the API, the service:

import { Injectable } from "@angular/core";
import { Http, Headers } from "@angular/http";
import { Observable } from "rxjs/Rx";
import "rxjs/add/operator/map";

import { Cat } from "./cat";

@Injectable()
export class CatListService {
constructor(private http: Http) {}

    load() {

        return this.http.get("http://10.0.1.24:3000/api/cats")
        .map(res => res.json())
        .map(data => {
            let catList = [];
            data.forEach((cat) => {
                catList.push(new Cat(cat.id, cat.name, cat.breed, cat.age));
            });
            return catList;
        })
        .catch(this.handleErrors);
    }

    get(id) {
        return this.http.get("http://10.0.1.24:3000/api/cats/"+id)
        .map(res => res.json())
        .map(data => {
            return new Cat(data.id, data.name, data.breed, data.age);
        })
        .catch(this.handleErrors);

    }

    handleErrors(error: Response) {
        console.log('in handleErrors');
        console.log(JSON.stringify(error.json()));
        return Observable.throw(error);
    }
}

The service consists of two methods, load and get. Both simply call the API. The load method gets everything, so it just hits api/cats while get retrieves a specific cat by simply appending an ID to the end. It’s almost embarrassingly easy, which is kind of the point.

Wrap Up

I hope that you’ve enjoyed this quick look at the LoopBack framework. Obviously I’m pretty biased, but I really fell in love with it within a few hours of playing with it. Feel free to ask me any questions in the comments below, and enjoy building your APIs!

Related resources:

Comments