Browser Support

LoopBack version 1.8.0 introduces browser support with two key features: The loopback.Remote connector and the browserify distribution. These enable running a LoopBack client application in the browser that shares code with a LoopBack server application. This means you can adopt the same programming model on both client and server.

What’s LoopBack? It’s an open source API server powered by Node for connecting devices and apps to data and services.

loopback_logo

A Brief Example

We start with a very bare-bones LoopBack server.

server.js

var loopback = require('loopback');
var server = module.exports = loopback();
var CartItem = require('./models').CartItem;
var memory = loopback.createDataSource({connector: loopback.Memory});

server.use(loopback.rest());
server.model(CartItem);
CartItem.attachTo(memory);

server.listen(3000);

Continuing with the example above, we’ll define our models in a separate file, so our server and client can require them. Notice there is a remote method, CartItem.sum(), and a standard prototype (instance) method, cartItem.total().

models.js

var loopback = require('loopback');

var CartItem = exports.CartItem = loopback.DataModel.extend('CartItem', {
  tax: {type: Number, default: 0.1},
  price: Number,
  item: String,
  qty: {type: Number, default: 0},
  cartId: Number
});

CartItem.sum = function(cartId, callback) {
  this.find({where: {cartId: cartId}}, function(err, items) {
    var total = items
      .map(function(item) {
        return item.total();
      })
      .reduce(function(cur, prev) {
        return prev + cur;
      }, 0);

    callback(null, total);
  });
}

loopback.remoteMethod(
  CartItem.sum,
  {
    accepts: {arg: 'cartId', type: 'number'},
    returns: {arg: 'total', type: 'number'}
  }
);

CartItem.prototype.total = function() {
  return this.price * this.qty * 1 + this.tax;
}

The following file is what is entirely new. This file would be the entry point for a browserify bundle and would run in the browser.

client.js (browser or Node.js)

var loopback = require('loopback');
var client = loopback();
var CartItem = require('./models').CartItem;
var remote = loopback.createDataSource({
  connector: loopback.Remote,
  url: 'http://localhost:3000'
});

client.model(CartItem);
CartItem.attachTo(remote);

// call the remote method
CartItem.sum(1, function(err, total) {
  console.log('result (calculated on the server):', err || total);
});

// call a built in remote method
CartItem.find(function(err, items) {
  console.log(items); // => [] of items in the server’s memory db
});

Take a look at the example in Github.

The remote connector

The remote connector enables clients to discover and call remote methods defined on the server. It works both in the browser and in Node.js. In the example above, sum is defined as a remote method.

loopback.remoteMethod(
  CartItem.sum,
  {
    accepts: {arg: 'cartId', type: 'number'},
    returns: {arg: 'total', type: 'number'}
  }
);

The remote connector used in the client uses the remoting metadata in the example above to create a shim method. The shim calls the sum method on the server over REST.

Browserify

Browserify lets you require modules in the browser by bundling up all of your dependencies. LoopBack is compatible with Browserify and can be required in your browserify app. Just create an entry script. We’ll use client.js from the example above. Creating a bundle file by running the command line tool:

Ω browserify client.js -o bundle.js

Browserify parses your JavaScript for require() calls to traverse the entire dependency graph of your project. Drop a single <script> tag into your html and you can run your LoopBack app in your browser.

What’s next?

Local Storage

The remote connector is just the beginning. We are working on a local storage data source that enables you to persist LoopBack models in local storage.

Replication

For mobile apps and offline-capable apps, simple CRUD APIs aren’t enough. We’re working on a new replication API that enables you to sync data between data sources.  Combined with a local storage data source, the replication API would make building offline apps very simple. The example below demonstrates the basic usage of the replication API. Calling LocalTodo.replicate(ServerTodo) will push all the data stored locally to the server.

// create a todo in local storage

LocalTodo.create({title: 'pick up milk from the store'});

// once you have a connection, sync it with the server

LocalTodo.replicate(ServerTodo);

Recap

LoopBack is coming to the browser! If you have any suggestions, comments or ideas, be sure to post to the mailing list or open an issue on github.

What’s next?

  • Install LoopBack with a simple npm command
  • What’s in the upcoming Node v0.12 version? Big performance optimizations, read the blog by Ben Noordhuis to learn more.
  • Need performance monitoring, profiling and cluster capabilites for your Node apps? Check out StrongOps!
  •