Introduction

Applications often need to store and use files such as images, videos, and PDFs. Nowadays, there are a lot of choices for cloud storage providers, each of which provides a different API. Meanwhile, web and mobile platforms provide different ways to upload and download files. The variety of storage providers and client APIs create complexity when developing applications that need to handle files.

The LoopBack storage service simplifies dealing with files by providing a unified REST API to enable web and mobile applications to upload, download, and manage binary contents using the  most popular storage providers: Amazon, Rackspace, Openstack, and Azure, as well as the local file system.

The architecture is illustrated below:

loopback-nodejs-storage-service-provider

 

LoopBack abstracts the management of content with two models:

  • Container provides a simple way to group objects. Think about container as a directory, a folder, or a bucket. Container defines the namespace for objects and is uniquely identified by its name, typically within a user account.
  • File stores the data content of an object, such as a document or image. A file is always placed in one (and only one) container. Within a container, each file has a unique name. Files in different containers can have the same name.
  • Note that a container cannot have child containers. The two-level hierarchy is chosen for simplicity and is the common pattern supported by most cloud storage providers.

    Storage service model APIs

    LoopBack provides simple APIs to manage containers and files.  The APIs are mixed into models that are attached to a data source configured with the loopback-storage-service connector; for example:

    var ds = loopback.createDataSource({
    connector: require('loopback-storage-service'),
    provider: 'filesystem',
    root: path.join(__dirname, 'storage')
    });
    var Container = ds.createModel('container');
    

    Now the container model will have the following methods:

  • getContainers(cb): List all containers
  • createContainer(options, cb): Create a new container
  • destroyContainer(container, cb): Destroy an existing container
  • getContainer(container, cb): Look up a container by name
  • uploadStream(container, file, options, cb): Get the stream for uploading
  • downloadStream(container, file, options, cb): Get the stream for downloading
  • getFiles(container, download, cb): List all files within the given container
  • getFile(container, file, cb): Look up a file by name within the given container
  • removeFile(container, file, cb): Remove a file by name within the given container
  • upload(req, res, cb): Handle the file upload at the server side
  • download(container, file, res, cb): Handle the file download at the server side
  •  

    Configure the storage providers

    Each storage provider takes different settings; these details about each specific provider can be found below:

    Local File System

    { provider: 'filesystem',
    root: '/tmp/storage' }
    

    Please note the root folder needs to exist. Create it first.

    Amazon

    { provider: 'amazon',
    key: '...',
    keyId: '...' }
    

    Rackspace

    { provider: 'rackspace',
    username: '...',
    apiKey: '...' }
    

    OpenStack

    { provider: 'openstack',
    username: 'your-user-name',
    password: 'your-password',
    authUrl: 'https://your-identity-service' }
    

    Azure

    { provider: 'azure',
    storageAccount: "test-storage-account", // Name of your storage account storageAccessKey: "test-storage-access-key" // Access key for storage account }
    

    REST APIs

    HTTP Method URI Description
    GET /api/containers List all containers
    GET /api/containers/:container Get information about specified container
    POST /api/containers Create a new container
    DELETE /api/containers/:container Delete specified container
    GET /api/containers/:container/files List all files within specified container
    GET /api/containers/:container/files/:file Get information for specified file within specified container
    DELETE /api/containers/:container/files/:file Delete a file within a given container by name
    POST /api/containers/:container/upload Upload one or more files into the specified container. The request body must use multipart/form-data which the file input type for HTML uses.
    GET /api/containers/:container/download/:file Download a file within specified container

     

    Client SDKs

    Coming soon! Native support for File objects in the LoopBack Android and client JavaScript SDKs.

    For a “sneak peek” of the HTML5/JavaScript implementation, see the W3C FileAPI spec.

    Run the demo

    $ git clone <a href="http://github.com/strongloop/loopback-storage-service.git">http://github.com/strongloop/loopback-storage-service.git</a><br /> $ cd loopback-storage-service<br /> $ npm install<br /> $ node example/app

    Now open your browser and point to http://localhost:3000.

    The client side code was derived from this example.

    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!