Chapter 2. Using RHMAP Features in Cloud Apps

2.1. Transforming JSON API responses with API Mapper

2.1.1. Overview

When accessing data from third-party APIs, it is often necessary to adapt the structure or format of the received data for your application. For example, by converting values to different formats, preprocessing the data and deriving new values, or by renaming or removing fields to fit the model of your application.

RHMAP contains a visual tool called API Mapper which lets you encapsulate the data transformation logic and abstract it away from your main application logic. API Mapper helps you with the task of transforming the responses of JSON APIs by letting you:

  • Rename fields.
  • Exclude fields that are not needed.
  • Transform field values using built-in or custom transformations.

2.1.2. Setup

API Mapper is provided as a Cloud Service template. A single instance of API Mapper can be used by multiple Cloud Apps and Cloud Services, and for transformation of multiple different APIs. However, you can deploy any number of API Mapper instances if necessary.

Follow these steps to start using API Mapper:

  1. Deploy API Mapper service.

    1. In the Services & APIs section, click Provision MBaaS Service/API.
    2. Find API Mapper in the list, and click Choose.
    3. Enter any name, such as API Mapper, and click Next.
    4. Choose an environment where API Mapper will be deployed after it is created, and click Next.
    5. Click Finish, and wait until the deployment finishes.
  2. Make the service public.

    In the Service Details page of the newly created API Mapper service, in the Access Control section, check Make this Service Public to all Projects and Services. Click Save Service. Make a service public

2.1.3. Usage Example

This example shows how to create requests, mappings, and custom transformations. For demonstration, this procedure uses the public Github API as an example of the source API to be transformed.

2.1.3.1. Creating a Request

Create a request for a Github API endpoint to get information about the feedhenry-templates/fh-api-mapper repository.

  1. From the home page of the API Mapper, click New Request.
  2. In the URL field, paste the full URL of the API request:

    https://api.github.com/repos/feedhenry-templates/fh-api-mapper
  3. Github API requires that the User-Agent header is sent with every request. Enter these values:

    • Header Key: User-Agent
    • Header Value: FHApiMapper
  4. Next, choose an internal mount path for this request. Select the Mount Path tab, and enter a path. This example uses /thisrepo as the mount path. The mapped request will be available at this path, which in this case results in the following URL:

    http://<serviceURL>/thisrepo
  5. Click Create Request to store the request in the database.
  6. Click Send Request to send the request and get a response.
  7. In the Response section, verify the Response Headers and Response Body sections appear as expected. You can now see the original response body before any transformation.

2.1.3.2. Adding a Mapping

After saving the request and mapping it to an internal path, choose transformations to apply to individual fields of the response. This step shows how to discard and rename fields, and transform field values.

  1. In the Response Mapping section, click Add a Mapping.

    Once the mapping is created, you can see a list of fields returned in the response on the left.

  2. Discard the owner field.

    Click the owner field to select it for editing in the Field Mapping panel, where you can define transformations on the field. Discard the owner field and all of its children by unchecking Use this field.

  3. Rename the id field to _id.

    Select the id field on the left. In the Rename Field box, type _id.

  4. Rename the private field to public and invert its value.

    As in the previous step, rename the field private to public. Then, select a transformation called invert in the Transform drop-down list.

Note

All changes made in the Field Mapping section are automatically saved.

After setting up the transformations, you can compare the original and the mapped response body in the Response Body tab of the Response section. The original response is on the left, the mapped response is on the right.

The mapped response now contains a public field with the value true, an _id field instead of id, and it does not contain an owner field.

2.1.3.3. Using the Mapped API

The Response section contains a Sample Code tab, which contains code snippets for invoking the mapped request from various clients, including:

For example, to invoke the request from the command line, copy the cURL Request snippet, paste it into a command line and execute the command. The mapped response is displayed in the console.

2.1.4. Custom Transformations

In addition to the built-in field transformations, you can also write custom transformation functions.

2.1.4.1. Writing Custom Transformations

To register a custom transformation function, you must declare it in the application.js file of API Mapper, in a configuration object passed to the function for the / route, as demonstrated in the following snippet:

app.use('/', require('./lib/api')({
  transformations : {
    <transformation name> : {
      type: <'array' | 'number' | 'string' | 'boolean'>,
      transform: <unary function>
    }
  }
}));

Custom transformations are defined as properties of the transformations object. The name of a property corresponds to the name of the transformation. The value of a property is a transformation definition object.

Each transformation definition object has two properties:

  • type: a string representing the JavaScript type of the input value. Possible values: array, number, string, boolean.
  • transform: the transformation function. The function takes the original field value as the only argument and returns the transformed value.

2.1.4.2. Example

This example shows how to create a transformation called even, which changes even numbers to 0 and odd numbers to 1.

  1. Navigate to the Editor of the API Mapper service and open the application.js file.
  2. Look for the declaration of the transformations object, which contains one existing custom transformation called mixedArrayTransform.
  3. Replace the value of the transformations property with the following object:

    {
      even: require('./transformations/even.js')
    }
  4. Create a new transformations/even.js file with the following contents:

    // First, tell the mapper it operates on numbers
    exports.type = 'number';
    // then, implement the function.
    exports.transform = function(n) {
      return n%2;
    };

The new transformation called even is now available in the API Mapper UI for numeric types.

2.2. Developing An Application Using Push Notifications

Overview

This tutorial will guide you through the process of building a sample application which receives push notifications sent from the Platform’s built-in push notification server. The application you’ll create in this example is based on Cordova and targets Android and the associated Firebase Cloud Messaging (formerly Google Cloud Messaging) platform. However, the steps are analogous for all other supported platforms.

To learn more about push notification support in the Red Hat Mobile Application Platform, see Push Notifications.

2.2.1. Obtain Firebase Cloud Messaging credentials and download the google-services.json file

For the built-in UnifiedPush Server (UPS) to be able to access Google’s push notification network, you first need to get a Server key and establish a project in the Firebase Console. See Obtaining Firebase Cloud Messaging Credentials for a detailed walk-through of getting the credentials. These instructions are for a native Android app, you do not need to complete all the process. In order to successfully complete the setup you need to obtain the following three items:

  • Server key (formerly API key)
  • Sender ID (formerly Project Number)
  • the google-services.json file generated from the Firebase console

For other push networks, see Obtaining Credentials for Push Networks.

2.2.2. Create a project from the Push Notification Hello World template

Push Notification Hello World template

  1. In RHMAP Studio, go to Projects and click New Project.
  2. Look for the Push Notification Hello World template, and click Choose on the right-hand side.
  3. Enter a name for the project in the Name your Project field.
  4. In the App Templates section, look for Simple Cordova Push App. Make sure this app is selected and deselect all other apps that can be deselected within the project template. The check boxes are in the top right corner of each app template.
  5. Click Create at the top right of the project template. Wait until the project creation is completed. Then click Finish at the bottom of the screen.

2.2.3. Define a package name for your Client App

  1. In the Apps, Cloud Apps & Services section of your project, click the Simple Cordova Push App.
  2. Click Config on the left side of the screen.
  3. Select the Android option in the Config menu.
  4. Define a package name for your Client App under Android Package Name.

    This name is required when registering your app in the Firebase Console. When defining the name of your package, observe the Java package naming convention.

    Define a name for your package

2.2.4. Set up push support

Push support needs to be explicitly enabled for each Client App and you also need to provide the push network credentials obtained in the first step Obtain Firebase Cloud Messaging credentials and download the google-services.json file.

Add Android variant

  1. In the Apps, Cloud Apps & Services section of your project, click the Simple Cordova Push App.
  2. Click Push on the left side of the screen.
  3. Click Enable Push.
  4. Select the Android option and enter the Server key and Sender ID obtained in the first step. Click Enable Push.

2.2.5. Integrate the google-services.json file into the Client App

  1. Click Editor on the left-hand side of the screen.
  2. Select the www folder in the Editor, click the + symbol in the toolbar to create a new file, and name it google-services.json.
  3. Open the google-services.json file you have previously downloaded from the Firebase Console, copy the contents into the google-services.json in the Editor.
  4. Click File, and then Save in the Editor toolbar to save your changes.

2.2.6. Configure config.xml file

Modify the widget id setting in the config.xml file to correspond to the package name defined in the Firebase Console.

2.2.7. Build the Client App binary

Build Client App binary for Android

We will build a Debug type of the Android binary which is easy to build without any special setup.

  1. Click Build on the left-hand side of the screen.
  2. In the Client Binary section, select Android.
  3. Click Build at the bottom of the screen and wait until the app is built. You can monitor progress at the bottom of the screen in the Artifact History section.
  4. Once the build is finished, a dialog with a download link and a QR code should pop up. Alternatively, click Download in the first line of the Artifact History table.
  5. With your mobile device, scan the presented QR code and install the app.

2.2.8. Test the app

Send push notification

  1. On your mobile device, open the newly installed Simple Cordova Push App.
  2. In RHMAP, open your project, and in Apps, Clouds & Services, open the Simple Cordova Push App.
  3. Click Push on the left side of the screen.
  4. Click Send Notification to this app at the top of the screen.
  5. Fill in the Message, keep all other fields unchanged, then click Send Push Notification.
  6. Shortly, your mobile device should receive a push notification with the provided message.

2.3. Dynamically Populating Form Fields From an MBaaS Service

2.3.1. Overview

You can use an endpoint of an MBaaS service as the data source for a form field in the Forms Builder. This guide shows you how to create the MBaaS service, define the data source, and populate a form field using the data source.

See Using Data Sources for more information on data sources for Forms.

2.3.2. Creating a Service for a Data Source

To define a data source, you must provide an MBaaS service endpoint which serves valid JSON responses for the data source. In this example, you’ll create a new MBaaS service which serves static data from a JSON file.

  1. In the Studio, navigate to Services & APIs. Click Provision MBaaS Service/API.
  2. On the left, choose the Data Sources category.
  3. Select a template. For example, Static Data Source.
  4. Choose a name for the service and deploy it to an environment.

2.3.3. Defining a Data Source

Once you’ve created the MBaaS service providing the data, you can now use it in a data source.

  1. In the Studio, navigate to Drag & Drop Apps > Data Sources. Click New Data Source.
  2. Set a name and a description. Both are required.
  3. Choose the previously created MBaaS service and its endpoint to use as the data source.

    The Static Data Source template used in this example serves data at the endpoint /static_ds/months.

    You can check, whether the service returns data valid for use as a data source, using the Validate button. Before the validation, make sure the correct environment is selected using the environment selector in the top right-hand corner.

    If the data is valid, you’ll see the message "Success Data Source Is Valid". If the data is not valid, or the service can not be reached, an error message will indicate the problem.

    After a successful validation, you can view the returned data using the View button.

    Choose a service and schedule

  4. Choose an update frequency – how often the configured MBaaS service endpoint will be called to obtain new data. The update frequency is a value in the range of 1 minute to 7 days.
  5. Choose how many responses from calls to the MBaaS service endpoint should be kept in the audit log.
  6. Click Create Data Source. You will see the message Data Source Created Successfully.

Now, the data source can be used in the Forms Builder to populate a form field.

2.3.4. Using a Data Source in a Form Field

After defining the data source, you can now use it in the Forms Builder.

  1. In the Studio, navigate to Drag & Drop Apps > Forms Builder.
  2. Open an existing form, or create a new form. Navigate to Edit Form.
  3. Drag one of the supported types into the form – for example, a Dropdown field. Select the created field.
  4. In the Options section, check Use a Data Source to populate field options?.
  5. Select the data source created in the previous step.

    Select a data source

    If a selected data source has loaded data at least once before – for example, while validating during creation – the last available version of the data will be displayed in the field options, as a preview.

    Use the environment selector in the top right-hand corner to ensure that the same environment is selected, where the MBaaS service of the data source is deployed.

  6. Save and deploy the form.

If you navigate to the Dashboard, you can now see the field populated by data from the data source in the preview on the right.

2.4. Adding Stats to your App

2.4.1. Overview

The Platform maintains counters and timers that can be accessed by the user. Some are provided by the platform, while others can be specified by the developers of an application.

Counters can be used to track the usage of particular functionality, counters can be incremented and decremented. The platform provides counters that show currently active server-side actions, that is, the number of server-side functions that have been called by a mobile application that are currently in progress.

Timers can be used to track the length of time taken by specified actions. The platform provides timers to track the execution-time of the server-side actions. Periodically, at a platform-configured interval, the current counters, and timers and pushed to a history and zeroed.

When requesting statistics from the platform, the number of recent intervals to return data for, and the length of the flush interval, in milliseconds, is returned with the data.

Timer data is returned as the number of timing events that have occurred in the interval, with upper and lower values, there are also upper and mean values for the 90th percentile.

2.4.2. Creating Counters and Timers

App developers can create their own counters and timers using:

$fh.stats.inc('COUNTERNAME'); // Increments a counter
$fh.stats.dec('COUNTERNAME'); // Decrements a counter
$fh.stats.timing('TIMERNAME', timeInMillis); // Store a timer value

For more detailed documentation about using the Stats API in your Cloud App, see:

Developers' counters and timers can be requested from the platform, by specifying the statstype of "app”.

The keynames of the counters are of the form DOMAIN_APPID_app_COUNTERNAME where DOMAIN_APPID is the name of the domain and APPID is the ID of the app, and COUNTERNAME is the developer supplied name for the counter.

The keynames of the timers are of the form DOMAIN_APPID_app_TIMERNAME where DOMAIN_APPID is the name of the domain and APPID is the ID of the app, and TIMERNAME is the developer supplied name for the timer.

2.4.3. Viewing Stats

A user can access stats data through the Studio or the raw data itself through FHC, the command line client.