Chapter 1. Developing Cloud Apps
1.1. Cloud Development
1.1.1. Overview
One of the core concepts in the Red Hat Mobile Application Platform Hosted (RHMAP) are Cloud Apps — server-side applications which handle communication between Client Apps deployed on mobile devices, and back-end systems which contain business logic and data.
Cloud apps are developed using Node.js — a platform built on Chrome’s JavaScript runtime for easily building fast, scalable network applications. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient, perfect for data-intensive real-time applications that run across distributed devices.
For those not familiar with Node.js development, the Node Beginner Website is an excellent resource.
1.1.2. Cloud App Structure
When a Cloud App is created in RHMAP, this newly created Cloud App is essentially a pre-configured Node.js application. If a corresponding pre-configured Client App is also generated, the Cloud App will include all basic configuration (routes) so that the Client and Cloud App are in sync. In addition, the infrastructure for hosting the Cloud App is also in place (MBaaS) and is easily accessible.
As the configuration and infrastructure are all in place, the Cloud App can be deployed to an MBaaS and is capable of routing the Client App’s requests without the need of additional code. Should an advanced Node.js developer wish to re-engineer the server or implement their own server, this is possible through the manipulation of the code within the application.js file.
Ensure that the file that represents the main entry point to your App is always called application.js.
The following files are provided by default in a Cloud App:
1.1.2.1. application.js
This file is invoked when your application is deployed to an MBaaS - our cloud execution environment. In most cases you will not need to touch this file - it is set to handle fh.cloud() requests from the client and route them accordingly.
1.1.2.2. package.json
The configuration file for your Cloud App is primarily used for dependency management. If you are using third-party Node modules, they will be specified in this file.
See also:
1.1.3. Example
There are only a few steps to get a Cloud App running. You can explore a simple example by trying the Hello World Project template when creating a new project in the Studio, or by looking at the source code of the template on GitHub: feedhenry-templates/helloworld-cloud. This is a brief overview of the template.
The first step is to configure a custom route in application.js:
app.use('/hello', require('./lib/hello.js')());
In the referenced hello.js file, you would define the logic for that particular route.
var express = require('express');
var bodyParser = require('body-parser');
var cors = require('cors');
function helloRoute() {
var hello = new express.Router();
hello.use(cors()); // enables cross-origin access from all domains
hello.use(bodyParser()); // parses POST request data into a JS object
hello.post('/', function(req, res) {
res.json({msg: 'Hello ' + req.body.hello});
});
return hello;
}
module.exports = helloRoute;
The client-side call to this endpoint using $fh.cloud might look like the following:
$fh.cloud({
path: 'hello',
data: {
hello: 'World'
}
},
function (res) {
// response handler
},
function (code, errorprops, params) {
// error handler
}
);1.2. Environments
1.2.1. What are Environments
Environments are a way of logically separating the development cycles of Projects, Services, Forms and Apps into discrete stages. Environments are a key part of Lifecycle Management.
For example, a Project could have 3 stages of development: Dev, UAT & Production. Each stage is represented by an Environment. The number and make up of Environments is configurable through the Platform and can be tailored on a per-domain basis.
1.2.2. How Environments interact with Business Objects
Below is a quick reference for identifying areas in the App Studio where Environments are utilised
- Projects (including Apps)
- Services
- Forms
- Admin > Auth Policies
Should you access these areas without access to any Environments, you will see a warning similar to the one below:
1.2.3. No Environments — reduced functionality
To perform most actions relating to Projects, Services, Forms and Apps in the App Studio, you will need to be able to access one or more Environments.
If you are currently unable to access any Environments, this could be because:
- Your current Team membership excludes you from utilising any Environments
- Your Administrator has not setup any Environments yet
1.2.3.1. Update Team Membership
To gain access to an Environment you (or an Administrator for your Domain) will need to:
-
Navigate to the
Admin > Teamsarea -
Alter a team you are a member of and grant members of this team access to the
Admin > Environmentbusiness object
For more details about administering Teams, see here.
1.2.3.2. Administrator Environment Setup
If you believe your Team setup and membership is correct, contact your local Administrator for further assistance. Environments need to be set up by an Administrator before access to them can be granted via Teams.
1.2.4. Other resources
1.3. Using Node.js Modules in Cloud Apps
1.3.1. Overview
This guide shows you how to include and use Node.js modules in your Cloud Apps. In the Red Hat Mobile Application Platform (RHMAP), you can use the modules of any Node.js package available in the registry to develop your Cloud Apps. In the public registry - npmjs.com - you can find thousands of packages - frameworks, connectors, and various tools.
Parts of functionality of RHMAP itself are exposed as node modules. For example, when you create a new Cloud App on the Platform, by default the package.json will include a node module called fh-mbaas-api, which is the cornerstone of the Mobile Backend As A Service (MBaaS) in RHMAP.
1.3.2. Getting Started with Node.js Modules
If you need a piece of functionality in your app and you don’t want to reinvent the wheel, it’s worth searching for existing modules on npmjs.com.
For example, if you want to use the Mongoose ODM framework, you can try looking at the official page of the mongoose package in the registry - npmjs.com/package/mongoose.
To use the latest version of the package in your project, running the following command in your Cloud App’s directory will install the package locally and add it as a dependency to the package.json file of your Cloud App:
npm install --save mongoose
Alternatively, you can add the dependency to package.json manually, by appending it at the end of the dependencies object, as in the following example:
{
"name": "my-fh-app",
"version": "0.2.0",
"dependencies": {
"body-parser": "~1.0.2",
"cors": "~2.2.0",
"express": "~4.0.0",
"fh-mbaas-api": "~4.9.0",
"mocha": "^2.1.0",
"request": "~2.40.0",
"mongoose": "~4.1.12" // added mongoose dependency
}
}At this point, you can start using the modules provided by the package. Often, the package page on npmjs.com contains instructions for usage and links to documentation. The next step common to all modules is requiring the module in your code to be able to use it:
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/my_database');
...In this example, the database URL is hard-coded in the source. A more common scenario, however, is using different databases for different stages of development life cycle - development, testing, production. This can be resolved by defining configuration values through environment variables.
1.3.3. Environment Variables
If any part of the configuration of your Cloud App - such as hostnames, usernames, or passwords - varies between life cycle stages, you can set such configuration values using environment variables. That allows you to make configuration changes without changing the code. Every Cloud App has an Environment Variables section in the Studio where you can create or remove variables, set values, or push the variables to a running instance of the app.
Environment variables are especially useful in combination with the ability to push different values to different environments. For example, you could be using a different database host for testing and for production. Another benefit is that sensitive configuration information can be stored outside of the code base of your application.
In a Cloud App, environment variables can be accessed through the process.env object. The previous example of a Mongoose connect call changed to use environment variables would look this way:
mongoose.connect('mongodb://' + process.env.MONGO_HOST + '/' + process.env.MONGO_DB);1.4. Node.js Dependency Management Using npm
1.4.1. Overview
npm, the node package manager, is a dependency management tool for Node.js and is an integral part of developing any Node.js application. In its principles, npm is similar to any other dependency management system, like Maven, Cocoapods, or NuGet:
-
projects declare dependencies in a standardized file -
package.jsonin case of Node.js; - packages are hosted in a central location - the npm registry at registry.npmjs.org;
- dependency versions can be specified explicitly, or using wildcards or ranges;
- versions of transitive dependencies can be decided automatically, or fixed (see Using an npm-shrinkwrap file);
-
packages are cached locally after installation (
node_modulesfolder).
For an introduction to using Node.js modules in your Cloud Apps, see Using Node.js modules in Cloud Apps.
1.4.2. npm and App Staging
When deploying your Cloud App, the npm command is run in your app’s environment, to download and install the dependencies of your app.
The first time your Cloud App is deployed, the build can take some time as a full npm install is performed.
For each subsequent deployment:
when deploying to a hosted MBaaS (RHMAP 3.x):
-
If the package.json file has changed from the previous deploy, RHMAP runs
npm update. - If no changes have been made to package.json, no npm command is run (neither update, nor install).
To perform a clean stage, and run
npm install:- In the Studio, check the Clean Stage check box in the Deploy section of the Cloud App
-
If using fhc, use the --clean option, that is,
fhc app stage <app-id> <env-name> --clean
-
If the package.json file has changed from the previous deploy, RHMAP runs
when deploying to a self-managed MBaaS (RHMAP 4.x):
- If either the gitref or the nodejs runtime are changed then a new docker image is built.
- If the gitref and Node.JS Runtime are unchanged from a previous build then the existing docker image is used where possible.
- To force a fresh image to be built use the Clean Stage check box in the Deploy section of the cloud App.
1.4.3. npm Best Practices
The fundamental best practice with npm is to understand how versioning works with node modules (see The semantic versioner for npm) and to avoid using * for any dependencies in package.json.
A handy tip for developing locally is to use the --save flag when installing a module using npm, for example, npm install request --save. The --save flag will append the new module to the dependencies section in your package.json with the version that has just been installed. We also recommend using a shrinkwrap file.
1.4.3.1. Using an npm-shrinkwrap file
An npm-shrinkwrap.json file locks down the versions of a package’s transitive dependencies so that you can control exactly which versions of each dependency will be used when your package is installed.
To create a shrinkwrap file, run:
npm shrinkwrap
Put the resulting npm-shrinkwrap.json file to the root directory of your Cloud App. When npm install is invoked on your app in RHMAP, it will use exactly the versions defined in the shrinkwrap file.
To learn more about shrinkwrap, see the official npm documentation - Lock down dependency versions.
1.4.4. Uploading node_modules
RHMAP allows you to commit your node_modules directory and to use this in your Cloud App, even though it’s not a recommended practice. That way, npm is not run at all when your app is staged (even if the clean option is specified), and whatever modules you’ve uploaded will be used to run your app. However, native node modules need to be compiled on the same architecture on which they execute, which might vary between instances of RHMAP.
1.5. Setting the Node.js version
1.5.1. Using fhc
Firstly ensure you have the latest version of fhc.
npm install -g fh-fhc
You can then use the fhc runtimes command to see which runtimes are available to you in an Environment.
fhc runtimes --env=dev
This command will output the version, for example, 4.8.4.
On the left is the name of the runtime and on the right is the particular version.
fhc app stage --app=<APP_GUID> --runtime=<node version>
To set the app’s runtime during a stage, add the <node version>, for example, 4.8.4.
This will set your apps runtime to v4.8.4 of node.
To change it to a different runtime, add the runtime argument to the stage command again
1.5.2. Using the studio
In the Studio from the deploy screen you can see the current runtime the app is set to. You can also set a new runtime here and then deploy your app.

Where did the comment section go?
Red Hat's documentation publication system recently went through an upgrade to enable speedier, more mobile-friendly content. We decided to re-evaluate our commenting platform to ensure that it meets your expectations and serves as an optimal feedback mechanism. During this redesign, we invite your input on providing feedback on Red Hat documentation via the discussion platform.