Appcelerator Blog

The Leading Resource for All Things Mobile

Migrating Node.ACS Applications to Arrow

0 Flares 0 Flares ×

On September 1, 2015, Appcelerator’s Node.ACS servers will be discontinued in favor of Arrow Cloud, which is part of the new 4.0 Platform.

If you have a Node.ACS application and the published URL is https://<SUBDOMAIN_TOKEN>.cloudapp.appcelerator.com, you’ll need to migrate to Arrow Cloud. This will generate a new URL you’ll also need to update in your client apps.

This post describes the migration process for Platform users on Team or Enterprise plans. These same steps are also detailed in the docs here. If you have a Node.ACS application and are on an Indie plan, please check out options at www.appcelerator.com/pricing/ or contact sales at sales@appcelerator.com.

Create an Arrow project

Before starting, first create an Arrow project by executing the command below in your workspace directory:

appc new -t arrow -n ArrowProject

package.json

If you have any special settings or dependencies in your Node.ACS project’s package.json file, add them to the same file in your new Arrow project. Do not overwrite any existing keys.

Express app instance

Node.ACS used Express 3.x, while Arrow Builder uses Express 4.x. For details about migrating to Express 4, see http://expressjs.com/guide/migrating-4.html.

Express version

To access the Express instance in an Arrow project, use the app property of the Arrow instance. For the API and Route components, an Arrow instance is passed to the request and response objects as the server property.

Example

var Arrow = require('arrow'),
    favicon = require('serve-favicon'),
    server = new Arrow();
server.app.use(favicon(__dirname + '/web/public/images/favicon.ico'));

socket.io instance

An Arrow application does not include socket.io by default. To include socket.io in an Arrow application:

  • In the package.json file, add socket.io as a dependency.
  • In the app.js, in the started event listener, load the socket.io module and pass it the server instance (Arrow instance’s server property), then make API calls to the socket.io instance. If you assign the socket.io instance to a property of the Arrow instance, you can access the socket.io instance with that property wherever an Arrow instance is passed to a method.
  • Any client-side code, such as the view templates, will need to include the socket.io.js client script. Note that when the client connects to the socket.io server (Arrow application), you will need to update the URL when switching between testing the project locally or when its published to Arrow Cloud.

Example

The following example creates a basic chat application.
Add socket.io as a dependency to the Arrow project.

//package.json
{
  ...
  dependencies: {
    ...
    'socket.io': '*'
  }
}

Loads the socket.io module and creates an instance.

//app.js
var Arrow = require('arrow'),
    server = new Arrow();
server.on('started', function () {
    // Creates a socket.io instance and attaches it to the Arrow instance
    this.io = require('socket.io')(this.server, {logger: this.logger});
    // Adds a connection listener 
    this.io.on('connection', function(socket) {
        console.log('a user connected ' + socket.id);
        // Listens for a new message
        socket.on('message', function(data) {
            // Alerts all clients there is a new message
            this.io.emit('message', data);
        });
    });
});
// start the server
server.start(); 

Then, add the socket.io client code to your views or other client-side code.

//web/views/chat.html


  
    
    
    
    
    
  
  
    

    Note you need to implement an Arrow Route to render the HTML.

    //web/route/chat.js
    var Arrow = require('arrow');
    var ChatRoute = Arrow.Router.extend({
        name: 'chat',
        path: '/chat',
        method: 'GET',
        description: 'Access the chat client',
        action: function (req, res) {
            res.render('chat');
        }
    });
    module.exports = ChatRoute; 

    app.js

    If you add any logic to the start() or stop() methods in the app.js file, you can add the same logic in the Arrow instance’s event listeners for the starting and stopping events, respectively.

    Example

    The Node.ACS project logs in and out of an ArrowDB account when the application starts and stops. The same method calls can be added to the event listeners in an Arrow application.

    //NodeACSProject/app.js
    var ArrowDB = require('arrowdb'),
        arrowDBApp = new ArrowDB('API_KEY');
     
    function start() {
        var data = {
            login: 'user',
            password: 'user'
        };
        arrowDBApp.usersLogin(data, function(err, result) {
            // Logic
        });  
    }
     
    function stop() {
        arrowDBApp.usersLogout(function(err, result) {
            // Logic
        }); 
    }
    //ArrowProject/app.js
    var Arrow = require('arrow'),
        server = new Arrow(),
        ArrowDB = require('arrowdb'),
        arrowDBApp = new ArrowDB('API_KEY');
    server.on('starting', function () {
        var data = {
            login: 'user',
            password: 'user'
        };
        arrowDBApp.usersLogin(data, function(err, result) {
            // Logic
        });  
    }
    server.on('stopping', function () {
        arrowDBApp.usersLogout(function(err, result) {
            // Logic
        }); 
    }
    server.start();

    config.json

    routes
    All routes declared in the config.json file of your Node.ACS application may be declared as:

    • Arrow route located in the web/routes folder of the Arrow project if the route renders UI. For details, see the example below and Arrow Web.
    • Arrow Model if the route is a simple data object stored in the cloud that you want to have standardized HTTP endpoints. For details, see Arrow Models.
    • Arrow API if the route performs more complex operations and you want to have a custom HTTP endpoint. For details, see Arrow APIs.

    Example

    The config.json file defines a route that when someone accesses SERVER_ADDRESS/foobar, the Node.ACS application executes the bar() method in the controllers/foo.js file.

    //config.json
    {
      "routes":
      [
        {"path": "/foobar", "method": "get", "callback": "foo#bar"}
      ]
    }

    To use the same route in Arrow, create a CommonJS module, which loads the arrow module, then call the module’s Router.extend() method to declare the route. Pass a dictionary to the extend() method with the following keys defined (all keys are required):

    Key Description
    name The name of your route.
    path The endpoint/path for your route.
    method HTTP verb (‘DELETE’, ‘GET’, ‘POST’ or ‘PUT’)
    description A description for your route. This is used for documentation purposes.
    action Function that allows you to interact with Arrow APIs and Models and send data to your template engine.

    Finally, expose the route using the modules.exports variable.

    //web/routes/foobar.js
    var Arrow = require('arrow');
    var Foobar = Arrow.Router.extend({
        name: 'foobar',
        path: '/foobar',
        method: 'GET',
        description: 'Does foo',
        action: function (req, res) {
            res.render('example');
        }
    });
    module.exports = Foobar;

    Filters

    All filters declared in the config.json file of your Node.ACS application may be declared as an Arrow Block module that can be assigned to the before property in the definition file of an Arrow Model or API.

    Websockets

    For all websockets declared in the config.json file of your Node.ACS application, you will need to add an event listener to the socket once a connection is established, which requires socket.io to be added to the project. For details, see the “socket.io instance” section above.

    Example

    The config.json file defines a websocket that whenever a newChatMsg is received, the Node.ACS application executes the receiveMessage() method in the websockets/chatroom.js file.

    //NodeACSProject/config.json
    {
      "websockets":  [
        {"event": "newChatMsg", "callback": "chatroom#receiveMessage"}
      ]
    }

    To use the same websocket in Arrow, first add socket.io as described in the socket.io instance section, then add a newChatMsg event listener for the socket in the connection event listener.

    //ArrowProject/app.js
     var Arrow = require('arrow'),
        server = new Arrow();
    server.on('started', function () {
        // Creates a socket.io instance and attaches it to the Arrow instance
        this.io = require('socket.io')(this.server, {logger: this.logger});
        // Adds a connection listener 
        this.io.on('connection', function(socket) {
            socket.on('newChatMsg', function(data) {
                // Add the receiveMessage() logic here from websockets/chatroom.js
            });
        });
    });
    // start the server
    server.start(); 

    Controllers Folder

    All logic declared in the Node.ACS controllers should be moved to the Arrow Route module in the web/routes folder of the Arrow project or Arrow API module. For details, see the config.json section above.

    Filters Folder

    All logic declared in the Node.ACS filters should be moved to the Arrow Block module.

    Websockets Folder

    All logic declared in Node.ACS websockets will need to be declared with the socket event listener, which requires socket.io to be added to the project. For details, see the config.json section above.

    Public Folder

    Copy all files in the public folder of your Node.ACS application to the web/public folder in the new Arrow project.

    Views Folder

    Copy all files in the views folder of your Node.ACS application to the web/views folder in the new Arrow project.

    Arrow also supports other template engines including Handlebars, Markdown and ReactJS.

    Run the Arrow project

    After you have made your changes, to test the project, run or publish the Arrow project. To run the Arrow project locally, execute the following command from the project’s directory:

    //appc run

    Publish the Arrow project

    To publish the Arrow project to the cloud, execute the following command from the project’s directory:

    //appc publish

    This will produce a new URL, different from that of your existing Node.ACS project. Follow the instructions in the Node.ACS section of the platform migration page to replace your existing Node.ACS project and update clients that use it.

    0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×

    Sign up for updates!

    Become a mobile leader. Take the first step to scale mobile innovation throughout your enterprise.
    Get in touch
    computer and tablet showing Appcelerator software
    Start free, grow from there.
    0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×