StrongLoop LoopBack is an extension of the Express framework. All documentation for creating a LoopBack application is available on StrongLoop's LoopBack documentation page.

Prerequisites and Assumptions

  1. NodeJS local development environment.
  2. Local installation of referenced node modules and client-side modules
  3. Access to account. See Getting Started with Orchestrate.
  4. Access to AppFog v2. See Getting Started with AppFog.

Creating the LoopBack Application

Below are the basics to create a simple application.

First install StrongLoop in your local environment. Once installed, you can generate the project structure from the command line:

slc loopback app-name

This tutorial uses "library" as the app-name and "book" as the single model name with properties "author", "title", and "isbn" (all strings). Set up your book model slc loopback:model using the default db (memory) datastore and select PersistedModel as the base model when prompted.

Take a look at the full project structure generated by StrongLoop.

Since you are going to use Angular for the client, delete server/boot/root.js that would normally handle client-side routing. Instead, edit server/middleware.json to point to the client static files. Angular will take it from there:

    "files": {
        "loopback#static": {
            "params": "$!../client"

Finally, add body-parser for the http session in server/server.js:


    var bodyParser = require('body-parser');
    var app = module.exports = loopback();

    // Enable http session
      extended: true


Setting up the Orchestrate Connection

Log into and use the dashboard to create a "book" collection under the application "library." Orchestrate will generate an application level API key.

Now you are ready to set up a datasource connection on your server, based on Orchestrate's API documentation. Create server/lib/dbConn.js:

    const ORCHESTRATE_KEY = "xxxx-xxx-xxxx-xxxx-xxxxx"; // API_KEY
    const BOOKS_COLLECTION = "books"; // name of the collection

    var Q = require('q');
    // use the Orchestrate NodeJS module
    var oio = require('orchestrate');
    // explicitly set the Datacenter used for the application
    oio.ApiEndPoint = "";
    // make the connection
    var db = oio(ORCHESTRATE_KEY);

     *  @constructor
    function DBConn() {

    DBConn.prototype.getAll = function() {
      return Q.promise(function(resolve, reject, notify) {
            function(result) {
              var books = [];
              addToList(result.body.results, books);
            function(error) {

    var addToList = function(resultsList, books) {
      if (resultsList && resultsList.length) {
        resultsList.forEach(function (result) {
          // add the key to the book for later reference.
          // This is Orchestrate's version of a generated id
          var key = result.path.key;
          result.value.key = key;

    module.exports = DBConn;

Now you need to add remote methods to common/models/book.js to use DBConn.

    var DatabaseConnection = require('../../server/lib/dbConn');

    module.exports = function(Book) {

      Book.getAll = function getAll(callback) {

        var returnData = {};

        new DatabaseConnection().getAll().then(
          function(books) {
            returnData.statusCode = 200;
            returnData.body = books;
            callback(null, returnData);
          function(error) {
            returnData.statusCode = 500;
            returnData.body = error;

      Book.remoteMethod("getAll", {
        http: {verb: 'get'}, // default is Post
        returns: {
          arg: "returnData",
          type: "object"

Creating the AngularJS Client

First create client/index.html:

    <html ng-app='library'>

    <link rel="stylesheet" href="vendor/bootstrap/dist/css/bootstrap.min.css"
      type="text/css" />

      <div class="container">
        <div ui-view></div>

      <script src="vendor/jquery/dist/jquery.min.js"></script>
      <script src="vendor/bootstrap/dist/js/bootstrap.min.js"></script>
      <script src="vendor/angular/angular.min.js"></script>
      <script src="vendor/angular-resource/angular-resource.min.js"></script>
      <script src="vendor/angular-ui-router/release/angular-ui-router.min.js"></script>
      <script src="js/app.js"></script>
      <script src="js/controllers/listController.js"></script>
      <script src="js/services/services.js"></script>
      <script src="js/services/lb-services.js"></script>

The "vendor" css and scripts come from using Bower with the .bowerrc file containing:

{"directory": "client/vendor"}

Now create the app, view, controller and service under the js directory.

client/js/app.js sets up the routes. I prefer to use angular-ui-router as it is a bit cleaner than ng-router. Also, note the use of "controllerAs." This is a wrapper for $scope that clearly delineates controller versus local scope within the html template.

    var libraryApp = angular.module('library', ['ui.router', 'listControls', 'libraryServices']);

    libraryApp.config(['$stateProvider', '$urlRouterProvider',
      function ($stateProvider, $urlRouterProvider) {

          .state('listBooks', {
            url: '/listBooks',
            templateUrl: 'views/listBooks.html',
            controller: 'ListController',
            controllerAs: 'listCtrl'

Next create the view. The ui-view tag in index.html will inject the html defined by the templateUrl in the state configuration.


    <div class="row">
      <div class="col-md-12 column">
        <div class="panel panel-default">
          <div class="panel-heading">
            <span class="h4">Library</span>
          <div class="panel-body">
              <table class="table table-striped">
                    <th col="title">Title</th>
                    <th col="author">Author</th>
                    <th col="isbn">ISBN</th>
                  <tr ng-show="listCtrl.errorMessage">
                    <td colspan="3" class="alert alert-danger text-center">
                  <tr ng-repeat="book in listCtrl.books">

Next comes the js/controllers/listController.js that will utilize a service to communicate with the server.

    angular.module('listControls', ['libraryServices'])
        .controller('ListController', [ '$state', 'dbService',
                function($state, dbService) {
                    var ctrl = this;
                    ctrl.errorMessage = null;
                    ctrl.getAllBooks = function() {
                            ctrl.errorMessage = null;

                            ctrl.books = [];
                                function(books) {
                                    ctrl.books = books;
                                function(error) {
                                    ctrl.errorMessage = error;

Now js/services/services.js that communicates with the backend through the (soon to be generated) lb-services.js file.

    angular.module('libraryServices', ['lbServices'])
    .service('dbService', ['$q', 'Book', function($q, Book) {
        var dbService = this;

        dbService.getAllBooks = function() {
          // return the promise
          return $q(function(resolve, reject) {

                function(response) {
                  var books = response.returnData.body;
                  if (books && books.length) {
                  } else {
                    reject("Library is empty.");

                function(errorData) {
                  if (errorData.status >= 400) {


In order to use 'lbServices' and inject the 'Book' model, you have to generate client/js/services/lb-services.js from the command line. Any time you make a change to a model, remember to regenerate this file. It may be best to create a gulp or grunt task.

From the application root directory run lb-ng server/server.js client/js/services/lb-services.js

Now you are ready to run the app locally. You can use the Orchestrate dashboard to create your first sample data.

Deploying to AppFog v2

These are the basic steps to deploy your Node.js application to AppFog v2. Please see Deploying a Node.js Application for more detailed information and links to other articles.

Update your package.json to tell AppFog how to start your app.

      "scripts": {
          "start": "node server/server.js" // or "gulp" or whatever you use

Create a manifest.yml in your application root directory for use with cf push

    - name: library
      host: library
      instances: 2
        NODE_ENV: production

Create a .cfignore file in your application root directory. This tells AppFog which files should not be pushed to production. I recommend adding:


When deploying a Node.js application, AppFog will run npm-install on the server, so there is no need to deploy the node_modules directory. server/boot/explorer.js exposes the LoopBack REST API to the public when present.

Create config.production.js that to utilize the AppFog provided port:

    var port = process.env.VCAP_APP_PORT; // use AppFog port environment variable
    module.exports = {
      port: port

Now you can cf login -u ... and deploy using cf push from your application root directory.