23 Calling APIs from Custom Code

As a service developer, you might want to access platform APIs, connector APIs, and other custom APIs from your custom code. The custom code SDK provides methods that simplify making requests to these APIs.

How to Send Requests to MCS APIs

You use custom code SDK methods to send requests to MCS APIs. When you call one of these methods, that method makes a RESTful HTTP call to the MCS API. This SDK makes the HTTP calls mostly transparent to you, but you’ll see that a method's arguments and its return value are similar to what you would see with a RESTful HTTP request and response.

These methods and their arguments conform to a common pattern. This section describes this pattern, and the following sections provide the details that are specific to the API’s methods:

Note:

Note: The purpose of the examples in this chapter is to illustrate how to interface with the custom code service. The examples are not intended to teach best practices for writing Node.js REST API implementations.

API Request Pattern

The custom code SDK methods that make requests to custom, platform, and connector APIs follow this pattern:

req.oracleMobile.<service>.<method>(required arguments, options, httpOptions)

The <service> identifies the API that you want to call.

  • For platform APIs, this is the name of the platform, such as storage, ums, or notification.

  • For connector APIs, this can be either connectors or connectors.<api>. Later, we discuss how to choose which one to use.

  • For custom APIs, this can be either custom or custom.<api>. Later, we discuss how to choose which one to use.

You use options to specify optional API-specific properties. The next section discusses the options properties that are shared by many of these methods. Each method description in the subsequent sections discusses additional options properties that apply to that method, if any.

The httpOptions argument is like the Node.js http.request(options) argument. You use this argument to pass properties not covered by required arguments and options. For example, if you need to pass the timeout property to specify the number of milliseconds to wait for a request to respond before terminating the request, then you would pass it in httpOptions. Another example of when you use httpOptions is to pass query parameters to a connector. To learn more about http.request(options), go to the API documentation at https://github.com/mikeal/request and scroll down to the section entitled "request(options, callback)".

Tip:

When you use httpOptions.qs to pass the query string, you can use encodeURIComponent(<string>) for the qs value to ensure that your code handles multibyte characters.

You can omit the options and httpOptions arguments. When you do so, they are treated as null values. Any value that you provide in options that affects a parameter in httpOptions overrides the httpOptions parameter. The methods ignore any property in the options and httpOptions arguments that they do not support.

Note:

You might notice that you don’t need to worry about authentication when you send requests to custom, platform, and custom APIs from custom code. The service re-uses the access token that’s passed into the custom code and takes care of authentication for you. With connectors, if you need to use different credentials for the external service, you can use options.externalAuthorization to pass the value to be used in the Authorization header for the external service.

To learn how to send direct requests to third-party web services without going through a connector, see Calling Web Services and APIs from Custom Code.

Common options Argument Properties

Several custom code SDK methods that access APIs accept an optional options argument, which is a JSON object. Here are the options properties:

Property Description Type Default Value
accept The value for the Accept header. Use this property to list the media types that you prefer for the response body. Note that for most methods, the media type for a response body is application/json. String Empty, which indicates no preference for response type.
contentType The value for the Content-Type header. This property specifies the content type of the request body. For most methods, this is application/json. String Empty. Note that if the inType is json, then the service sets the Content-Type header to application/json.
inType For Storage, connector API, and custom API SDK functions that take a request body, use this option to specify whether the request body is json or stream.

If json, then the method sets the Content-Type header to application/json automatically.

You typically set this property when the custom code builds the request body that you are sending to the API.

String Undefined. If this property isn’t set, then the method passes the request body as is. The request is serviced by the Node Request module, which accepts a string or a buffer.
outType The response body type. The value can be one of the following:
  • json: Convert the response body to a JSON object. Note that if there are JSON parse errors, then the response body remains a string.

  • stream: Return the response body in a readable stream that can be piped.

  • binary: Do not convert the response body to a string.

  • encoding: Convert the response body to a string using the specified encoding.

This property is supported only by the Storage API and the connector and custom APIs. All other APIs use the default response behavior.

String Undefined. The response body is converted to a string using the UTF8 encoding.
encodeURI

When true, encodes the URI and the following arguments and properties:

  • Encodes table, keys, fields, extraFields, primaryKeys, and sql arguments and properties for database methods

  • Encodes collectionId, mobileName, objectId, orderBy, and user arguments and properties for storage methods.

This option is useful for multibyte characters.

Boolean false

API Response Patterns

The return value for a custom code SDK call to an API depends on the value of the options.outType property.

  • If the outType is stream, then, if there’s no error, the return value is a stream that you can pipe, as shown in Handling a Stream.

  • If the outType is undefined or any value other than stream, then the return value is a promise object. To learn more about the promise object, see Handling a Promise.

Handling a Stream

When the response is a stream, then, if there’s no error, the return value is a stream that you can pipe. Otherwise, you can process the error as shown in this example:

  req.oracleMobile.storage.store('attachments', req, {
    mobileName: 'Technician Notes',
    contentType: req.header('content-type'),
    inType: 'stream',
    outType: 'stream'
  })
  .on('error', function (error) {
    res.status(error.status).send(error.message);
  })
  .on('response', function (response) {
    console.info('HEADERS received from response:', response.headers);
  })
  .pipe(res);

For more information about streaming, see https://github.com/request/request.

Handling a Promise

A promise provides access to the result of an asynchronous request. At the time a promise is returned, the request may or may not have completed. Most custom code SDK methods return promises. In the following examples, <promiseFunction> represents a custom code SDK method that returns a promise, such as req.oracleMobile.storage.getCollections.

When you call a promise function, you typically use the then function to handle the success or failure as shown here:

<promiseFunction>.then(successFunction, errorFunction)
  • <promiseFunction> is the call that returns a promise, such as req.oracleMobile.storage.getCollections in the next code example.

  • successFunction is a user-defined function that is called if the prior promise function resolves successfully. This occurs when the request completes with a response status code less than 400. The successFunction takes a single argument, which is what the prior <promiseFunction> returned on success. With custom code SDK methods, this is a JSON object with the following properties:

    • result: The body of the result.

    • statusCode: The HTTP status code.

    • headers: A JSON object that contains all the HTTP response headers, such as {accept-charset:'UTF-8',content-type:'application/json'}.

    • contentType: The value of the Content-Type header if that header was included in the response.

    • contentLength: The value of the Content-Length header if that header was included in the response.

  • errorFunction is a user-defined function that is called if and when promise function doesn’t resolve successfully. This is when the response status is equal to or greater than 400, or if there is a severe error. The errorFunction takes a single argument, which is what the <promiseFunction> returned on error. With custom code SDK methods, this is a JSON object with the following properties:

    • statusCode: The HTTP status code.

    • error: The body of the error or the error message.

    • headers: All the response HTTP headers.

Note:

The then function takes an optional progressFunction argument. However, the custom code SDK doesn’t use this argument, and you can omit it from the call.

Here’s an example of how to call a custom code SDK method to access a custom, platform, or connector API and use then to handle the promise that it returns. In this example:

  • In this example, the <promiseFunction> is req.oracleMobile.storage.getCollections. This is a function from the storage component of the custom code SDK, which either resolves with a successful promise or rejects with an error promise.

  • If getCollections completes successfully, then it passes the successful promise to the first argument for then, which is function(result).

  • If getCollections results in an error, then it passes the error promise to the second argument, which is function(error).

// Get metadata about the backend's collections.
service.get('/mobile/custom/incidentreport/collections',
  function (req, res) {
    req.oracleMobile.storage.getCollections({sync: true}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    ); 
});

A promise and its result can be assigned to a variable. This means that the result can live longer than the function call alone, allowing you to chain multiple success and failure functions calls against the result. For example, you can write code like this:

var collections = req.oracleMobile.storage.getCollections({sync: true});

collections.then(successFunction1, errorFunction1);
...
collections.then(successFunction2, errorFunction2);

Note:

Because the custom code SDK uses the Bluebird promises library, we recommend that you use this library to process these promises. If you only use the then() function from the promises library, then you don’t need to include Bluebird in your package.

There are several promises libraries that you can choose from for your custom code implementation, but the extent to which they will work with the custom code SDK promises is not known. To learn more about Bluebird promises, go to https://github.com/petkaantonov/bluebird.

The next sections show some common examples of ways in which you can handle promises.

Chaining Calls

When you need to invoke a series of calls in a synchronous manner, waiting for one operation to complete before starting the next one, then you can take advantage of the fact that most custom code SDK methods return a promise. A promise handles some of the complexity of making synchronous calls in an asynchronous environment like Node, and provides a simple way to handle both success and failure cases through callback methods.

As we discussed in API Response Patterns, the simplest way to extract the result of a promise is to use the then function.  In your custom code, you can provide two arguments to the then function.

  • A function to invoke on success, which takes a single argument – the success promise.

  • A function to invoke on error, which takes a single argument – the error promise.

Here’s an example of using the then function to handle the result of a promise function. As you can see, it has two arguments:

  • function(result), which sends the getById result.

  • function(error), which sends the error message.

service.get('/mobile/custom/incidentreport/attachments/:id',
  function (req, res) {
    req.oracleMobile.storage.getById('attachments', req.params.id, {sync: true}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

When you need to call more than one API operation from a route definition, you can use then to chain the calls, so that one call completes successfully before the next one is called. In this example, the route definition:

  1. Posts an incident to the database and returns the result.

  2. If the post completes successfully, gets the user info.

  3. If the user info is retrieved successfully, posts an analytics event.

Notice that none of the then functions take a second argument (the error function). If an error (rejected) promise is passed to a then function that doesn’t have a second argument, then the code skips to the first then function with a second argument. In this example, because there aren’t any, all errors trickle to the catch function.

service.post('/mobile/custom/incidentreport/incidents',
function (req, res) {

  /* Post the incident and send the response. 
   * Then, if the post was successful,
   * get the username,
   * then use the username to post an event.
   * 
   **/
  postIncident()
  .then(getUser)
  .then(postEvent)
  .catch(function (errorResult) {
        console.warn(errorResult);
  });

  function postIncident() {
    return req.oracleMobile.database.insert('FIF_Incidents', req.body)
    .then(
      function (successResult) {
        res.status(successResult.statusCode).send(successResult.result);
        // By default, Bluebird wraps this with a
        // resolved promise
        return {status: "resolved"};
      },
      function (errorResult) {
        res.status(errorResult.statusCode).send(errorResult.error);
        throw errorResult;
      }
    );
  };

  function getUser() {
    return req.oracleMobile.ums.getUser({fields: 'username'});
  };

  function postEvent(successResult) {
    var userName = successResult.result.username;
    /*
     * Record the NewIncident event
     */
    var timestamp = (new Date()).toISOString();
    // Events are posted as an array
    var events = [];
    // Put events in context
    events.push(
      {name: 'context',
        type: 'system',
        timestamp: timestamp,
        properties: {userName: userName}
      });
    // Start the session
    events.push(
      {name: 'sessionStart',
        type: 'system',
        timestamp: timestamp
      });
    // Add the custom event:          
    events.push(
      {name: 'NewIncident',
        type: 'custom',
        component: 'Incidents',
        timestamp: timestamp,
        properties: {customer: req.body.customer}
      });
    // End the session:
    events.push(
      {name: 'sessionEnd',
        type: 'system',
        timestamp: timestamp
      });          
    // Post the batch of events. Apply the passed-in session ID to all.
    // The postEvent result is returned by this function
    return req.oracleMobile.analytics.postEvent(
      events,
      {sessionId: req.header('oracle-mobile-analytics-session-id')});  
  };
});
Joining Calls

Promise.join lets you make several asynchronous calls and then use the results after all calls are complete. The promise that the join returns is an array of the results.

For example, the following code makes three calls to the incidentreport custom API to get information for the result body. After all calls complete successfully, the then function’s success handler extracts the necessary information to compile the result, and then sends it.

Note that the join functions aren’t necessarily called in the order in which they occur in the code. The only guarantee is that all the join functions successfully complete before a success promise is returned.

/* Promise.join example
 *
 * Promise.join takes multiple promises as arguments.
 * If all promises succeed, then it returns a promise
 * that holds an array of the results of the promises.
 */
var Promise = require("bluebird");
module.exports = function(service) {
  ...
  service.get('/mobile/custom/incidentreport/join/:custId/:incidentId/:techId', function (req, res) {
    // Three functions that return promises.
    var customer = req.oracleMobile.custom.incidentreport.get(
      "customers/" + req.params.custId, {outType: 'json'});
    var incident = req.oracleMobile.custom.incidentreport.get(
      "incidents/" + req.params.incidentId, {outType: 'json'});
    var technician = req.oracleMobile.custom.incidentreport.get(
      "technicians/" + req.params.techId, {outType: 'json'});
 
    Promise.join(customer, incident, technician).then(
      function (joinResult) {
        // Anonymous handler that's called if all 3 promises succeeded.
        // Harvest a piece of data from each promise result.
        var report = {
          customerContact: joinResult[0].result.email, 
          description: joinResult[1].result.title, 
          technicianContact: joinResult[2].result.email};
        res.type('application/json');
        res.status(200).send(report);
      },
      function (error) {
        // Anonymous handler to handle errors
        console.info(error);
        res.status(error.statusCode).send(error.error);
      }
    );
  })  
  ...
}
Waiting for a Dynamic Set of Calls to Complete

Use Promise.all when you have a dynamic set of calls and you must wait until all calls complete before you take some action. If any of the promises in the array don’t succeed, then the returned promise is rejected with the reason for rejection.

/* Promise.all example
 *
 * Promise.all takes an array of promises as an argument (promiseArray).
 * If all promises succeed, then it returns a promise that holds
 * an array of the results from the promiseArray's promises.
 */

var Promise = require("bluebird");
module.exports = function(service) {
...
  service.get('/mobile/custom/incidentreport/all/:custId/:incidentId/:techId', function (req, res) {
    // Put the functions that return promises in the array
    promiseArray = [];
    promiseArray.push(req.oracleMobile.custom.incidentreport.get(
      "customers/" + req.params.custId, {outType: 'json'}));
    promiseArray.push(req.oracleMobile.custom.incidentreport.get(
      "incidents/" + req.params.incidentId, {outType: 'json'}));
    promiseArray.push(req.oracleMobile.custom.incidentreport.get(
      "technicians/" + req.params.techId, {outType: 'json'}));
    // Call Promise.all with the array
    Promise.all(promiseArray).then(
      function (allResult) {
        var report = {
          customerContact: allResult[0].result.email, 
          description: allResult[1].result.title, 
          technicianContact: allResult[2].result.email};
        res.type('application/json');
        res.status(200).send(report);
      },
      function (error) {
        console.dir(error);
        res.status(error.statusCode).send(error.error);
      }
    );
  })
  ...
}
Creating a Function that Returns a Promise

Here are some examples of creating and using functions that return a promise. The first example shows how to return a resolved promise and a rejected promise.

// Simple function that returns a resolved promise.  
// Note the object passed to Promise.resolve is the 
// object the promise is resolved with.
function resolve() {
  return Promise.resolve({status: "resolved"});
}

// Simple function that returns a rejected promise.  
// The object passed to Promise.reject describes the error.
function reject() {
  return Promise.reject({error: "rejected"});
}

In this example, the compareEtags function takes a successful (resolved) promise as its argument. It rejects the promise if the request had an ETag header and the ETag for the result doesn’t match the ETag passed in the header.

var Promise = require("bluebird");
var etag = require('etag');
module.exports = function(service) {
...

  service.get('/mobile/custom/incidentreport/incidents/:id/ifmatch', function (req, res) {
    function compareEtags(result) {
      thisEtag = result.headers.etag;
      if (req.header('if-match') &&
        thisEtag != req.header('if-match')) {
        return Promise.reject({
          statusCode: 412,
          error: "Precondition Failed" +". If-Match ETag: " + req.header('if-match') + ", this Etag: " + thisEtag
        })
      } else {
        // result is already a resolved promise
        return result;
      }
    }
    // The custom code SDK get method returns a promise,
    // which is then passed to the custom function compareEtags.
    // On success, compareEtags passes the result from the get.
    // If there's an ETag header, then the function rejects the 
    // promise if the result's ETag doesn't match.
    // 
    // All rejections are caught by the last then.
    req.oracleMobile.custom.incidentreport.get(
      "incidents/" + req.params.id, {outType: 'json'})
      .then(compareEtags)
      .then(
        function (result) {
          // res.setHeader('Etag', etag(JSON.stringify(result.result)));
          res.status(result.statusCode).send(result.result);
        },
        function (error) {
          res.status(error.statusCode).send(error.error);
        }
      );
  });
...
}

Accessing Mobile Backend Information from Custom Code

The MBE API lets you inquire about the mobile backend that the request is coming from.

This API has one method.

mbe.getMBE()

This method retrieves information about the backend that made the request. Note that this method is synchronous and doesn't return a promise.

Arguments

This method doesn’t have any required arguments and doesn’t take the options and httpOptions arguments.

Response

The response body is a JSON object that contains the name, version, and id properties.

Examples

Here’s an example of calling this method to get the backend’s name and version number to pass to the Notifications API:
  service.get('/mobile/custom/incidentreport/notifications',
    function (req, res) {
      req.oracleMobile.notification.getAll({
        mbe: req.oracleMobile.mbe.getMBE().name,
        version: req.oracleMobile.mbe.getMBE().version})
      .then(
        function (result) {
          res.status(result.statusCode).send(result.result);
        },
        function (error) {
          res.status(error.statusCode).send(error.error);
        }
      );
    });
Here’s an example of the JSON object that the method returns:
{   
  name: 'myMBE',   
  version: '1.0',   
  id: 'ab72abb7-b337-4673-8584-ca5163df5d24' 
}

Calling Platform APIs from Custom Code

You can use the req.oracleMobile.<service> methods to call a platform API, where <service> identifies the platform that you want to call. These subsections provide the details for each platform:

Further details, such as the HTTP response status codes and the schema for the request and response bodies, can be found in REST APIs for Oracle Mobile Cloud Service.

Accessing the Analytics API from Custom Code

The Analytics API lets you log runtime events, such as a user submitting an inquiry or placing an item into a shopping cart, so that you can observe performance and usage patterns.

For information about what you can do with the posted events and how you can report on them, see Analytics.

This API has one method.

analytics.postEvent(events, options, httpOptions)

This method accepts a batch of events and validates them. If they are valid, they are sent to the Analytics database. If one or more events in a batch are not valid, then no events are sent to the Analytics database.

When adding events to the batch, keep the following in mind:

  • There are two types of events — custom and system. Use the custom events to record the events that you want to analyze. Use the system events to group your custom events. Note that if you don't specify the event type, then the event defaults to custom. To learn more about each type, see:

  • Events are JSON objects. All events must have a name and a timestamp, and component and properties are optional.

  • With custom events, you can add your own custom properties to properties. For example:

    {
      name: 'NewIncident',
      type: 'custom',
      component:  'Incidents', 
      timestamp: timestamp,
      properties: {customer: 'Lynn White'}
    }

    Custom properties must be strings and the property names can’t be reserved names. For the list of reserved names, see Adding Custom Properties to Events.

  • You can group events by session. For example, a session can mark the beginning and ending of a function within the application or when an application starts and stops. You start a session by adding a system event with the name sessionStart. You use a sessionEnd event to end the session.

    You use a user-defined session ID to associate events with a session. You have two ways to specify a session ID for an event. You can add a sessionId property to an event, and you can set the options.sessionId property. Here’s examples of starting and stopping a session. In these examples, the session ID is set explicitly, but you can also set it using options.sessionId.
    {
      name: 'sessionStart',
      type: 'system',
      sessionId: '2d64d3ff-25c7-4b92-8e49-21884b3495ce',
      timestamp: timestamp
    }
    {
      name: 'sessionEnd',
      type: 'system',
      sessionId: '2d64d3ff-25c7-4b92-8e49-21884b3495ce',
      timestamp: timestamp
    }
  • If you want to provide context to a session, then precede the sessionStart event with a system event named context. You can also intersperse context events with custom events to indicate changes in context, such as a location change. Here’s an example of a context event:

    {
      name: 'context',
      type: 'system',
      timestamp: timestamp,
      properties: {
        userName: 'joe',
        model: 'iPhone5,1',
        longitude: '-122.11663',
        latitude: '37.35687',
        manufacturer: 'Apple',
        osName: 'iPhone OS',
        osVersion: '7.1',
        osBuild: '13E28',
        carrier: 'ATT'
    }
  • To associate the batch of events with an application, include the options.applicationKey property set to the application's key.

For information about what you can do with the posted events and how you can report on them, see Analytics.

Arguments

events: Required. This is an array of event objects. To learn about the event properties, see the POST /mobile/platform/analytics/events operation in REST APIs for Oracle Mobile Cloud Service.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
applicationKey Identifies the application key that MCS assigns to your application when you register it with the mobile backend. You can find this key in the Clients page for the mobile backend. For example, 9a5b4150-c756-4758-87c3-ec2814289799. String None
deviceId Identifies the device. This is the ID that is returned when you register the device with MCS using the Devices API. String None
sessionId Specifies a default session ID. Use a session ID to group all events by a user-defined session. When present, the sessionID value in the event object overrides this value. String None

Response

The response body is a JSON object with a message attribute. For example, {"message":"1 events accepted for processing."}

Example

Here’s an example that records events when incidents are created. After it successfully saves an incident in the database, it gets the user name for the context event, and then it records the event. This example uses the promises then() function to insure that each API call completes successfully before invoking the next, as described in Chaining Calls.

In this example, the request body looks like this:

{
  title:'Water heater is leaking', 
  technician:'jwhite',
  customer:'Lynn Smith'
}

This code expects the request to include the session ID in the Oracle-Mobile-Analytics-Session-ID header. It sets the options.sessionId property to this value.

service.post('/mobile/custom/incidentreport/incidents',
function (req, res) {

  /* Post the incident and send the response. 
   * Then, if the post was successful,
   * get the username,
   * then use the username to post an event.
   * 
   **/
  postIncident()
  .then(getUser)
  .then(postEvent)
  .catch(function (errorResult) {
        console.warn(errorResult);
  });

  function postIncident() {
    return req.oracleMobile.database.insert('FIF_Incidents', req.body)
    .then(
      function (successResult) {
        res.send(successResult.statusCode, successResult.result);
        // By default, Bluebird wraps this with a
        // resolved promise
        return {status: "resolved"};
      },
      function (errorResult) {
        res.send(errorResult.statusCode, errorResult.error);
        throw errorResult;
      }
    );
  };

  function getUser() {
    return req.oracleMobile.ums.getUser({fields: 'username'});
  };

  function postEvent(successResult) {
    var userName = successResult.result.username;
    /*
     * Record the NewIncident event
     */
    var timestamp = (new Date()).toISOString();
    // Events are posted as an array
    var events = [];
    // Put events in context
    events.push(
      {name: 'context',
        type: 'system',
        timestamp: timestamp,
        properties: {userName: userName}
      });
    // Start the session
    events.push(
      {name: 'sessionStart',
        type: 'system',
        timestamp: timestamp
      });
    // Add the custom event:          
    events.push(
      {name: 'NewIncident',
        type: 'custom',
        component: 'Incidents',
        timestamp: timestamp,
        properties: {customer: req.body.customer}
      });
    // End the session:
    events.push(
      {name: 'sessionEnd',
        type: 'system',
        timestamp: timestamp
      });          
    // Post the batch of events. Apply the passed-in session ID to all.
    // The postEvent result is returned by this function
    return req.oracleMobile.analytics.postEvent(
      events,
      {sessionId: req.header('oracle-mobile-analytics-session-id')});  
  };
});

Accessing the App Policies API from Custom Code

The App Policies API lets you retrieve the app policies that have been set for the current mobile backend. For example, a mobile backend might have app policies for the string that appears in an app’s welcome message, the background color, and a timeout value.

This API has one method.

appConfig.getProperties(httpOptions)

This method retrieves the app policies that have been set for a mobile backend. These are the policies that you create from the mobile backend’s App Policies page.

See App Policies.

Arguments

This method doesn’t have any required arguments and doesn’t take the options argument.

Response

The response body is a JSON object where the name/value pairs represent the app policies.

Examples

Here’s an example of calling this method:
service.get(
  '/mobile/custom/incidentreport/appPolicies',
  function (req, res) {
    req.oracleMobile.appConfig.getProperties().then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });
Here’s an example of the response body:
{
  "fifBgColor": "blue",
  "fifWelcomeMessage": "Hello",
  "fifShowArg": true
}

Accessing the Database Access API from Custom Code

You can use the Database Access API to retrieve, add, update, and delete rows in a database table. When you add a row, the API implicitly creates the table if it doesn't exist.

This API has the following methods:

For detailed information about how to use these methods to create and access database tables, see Database.

database.delete(table, keys, options, httpOptions)

This method lets you delete a row from the table.

Arguments

table: Required. String. The name of the database table to delete the row from.

keys: Required. String. If the table’s row key is id, then provide the id value. Otherwise, provide the primary key values in the order in which the primary keys were specified when the first row was added to the table (which resulted in the creation of the table). Use an array for a composite key. For example, if the options.primaryKeys property was set to incidentReport,technician when the table was created, then the values must be listed in that order, such as ['5690','jwhite'].

options: Optional. JSON object. This object can have the following property in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the table and keys values. This option can be useful for multibyte values. Boolean false

Response

The response body is a JSON object. If the table’s row key is id, then the response is an array that contains the deleted row’s id value. Otherwise, the response is the rowCount indicating if 0 or 1 row was deleted.

Examples

Here’s an example of calling the method to delete a record with the id specified in the request URI:

service.delete('/mobile/custom/incidentreport/incidents/:id',
  function (req, res) {
    req.oracleMobile.database.delete(
      'FIF_Incidents', req.params.id).then(      
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response for this request.

{"items":[{"id":42}]} 

Note that if you have defined primary keys for the table (instead of using the system-defined id column for the row key), then the response shows the rowCount of the deleted rows. For example:

{
  "rowCount": 1
}
database.get(table, keys, options, httpOptions)

This method lets you retrieve a row from a table.

Arguments

table: Required. String. The name of the database table to retrieve the row from.

keys: Required. String. If the table’s row key is id, then provide the id value. Otherwise, provide the primary key values in the order in which the primary keys were specified when the first row was added to the table (which resulted in the creation of the table). Use an array for a composite key. For example, if the options.primaryKeys property was set to incidentReport,technician when the table was created, then the values must be listed in that order, such as ['5690','jwhite'].

options: Optional. JSON object. This object can have the following property in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the table and keys values. This option can be useful for multibyte values. Boolean false
expectSingleResult Set to true to return an object instead of an array and to return 404 (not found) if the row for the specified keys doesn’t exist. Boolean false

Response

By default, the response body is a JSON object containing an items array with just one item, which contains the column names and corresponding values. To return a single object, include options.expectSingleResult in the request and set it to true.

Examples

Here’s an example of calling the method to retrieve the row with the id specified in the request URI. Because the expectSingleResult option is omitted, the response body will contain an array, and the response status will always be 200.

service.get('/mobile/custom/incidentreport/incidents/:id',
  function (req, res) {
    req.oracleMobile.database.get(
      'FIF_Incidents', req.params.id).then(      
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response for this request.

{
  "items":[
    {
      "id":2,
      "createdBy":"jdoe",
      "createdOn":"2018-01-31T20:14:24.4948+00:00",
      "modifiedBy":"jdoe",
      "modifiedOn":"2018-01-31T20:14:24.4948+00:00",
      "title":"Water heater is leaking",
      "technician":"jwhite",
      "status":"Open",
      "customer":"Lynn Smith",
      "incidentReport":"7890"
    }
  ]
}

Here’s an example of including the expectSingleResult option with a value of true. The response body will contain an object, and the response status will be 404 if the row doesn’t exist.

service.get('/mobile/custom/incidentreport/incidents/:id',
  function (req, res) {
    req.oracleMobile.database.get(
      'FIF_Incidents', req.params.id, {expectSingleResult: true}).then(      
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response for this request.

{
    "id": 2,
    "createdBy": "jdoe",
    "createdOn": "2018-01-31T20:14:24.4948+00:00",
    "modifiedBy": "jdoe",
    "modifiedOn": "2018-01-31T20:14:24.4948+00:00",
    "title": "Water heater is leaking",
    "technician": "jwhite",
    "status": "Open",
    "customer": "Lynn Smith",
    "incidentReport": "7890"
}
database.getAll(table, options, httpOptions)

This method lets you retrieve the specified fields from all the rows in a table.

Note:

The Database_MaxRows environment policy restricts the number of rows that the service returns for this call. The default value is 1000. Ensure that this value is sufficient for your needs. If your request doesn’t return all the rows that you expected, ask your mobile cloud administrator to increase the Database_MaxRows value.

Arguments

table: Required. String. The name of the tables to retrieve the rows from.

options: Optional. JSON object. This object can have the following properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the table and fields values. This option can be useful for multibyte values. Boolean false
fields A comma separated list of the fields to return. For example, customer, status. String If you omit this argument, then the method returns all fields.

Response

The response body is a JSON object containing an items array, where each item represents a row, and contains the column names and corresponding values.

Examples

Here’s an example of calling the method to retrieve the customer and status fields from the FIF_Incidents table:

service.get('/mobile/custom/incidentreport/incidents',
function (req, res) {
    req.oracleMobile.database.getAll(
      'FIF_Incidents', {fields: 'customer,status'}).then(    
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response for this request.

{
  "items":[
    {
      "status":"Open",
      "customer":"Lynn Smith"
    },
    {
      "status":"Completed",
      "customer":"John Doe"
    }
  ]
}

The /database/objects/{table} resource supports a query parameter to filter by column values which rows to retrieve. This example uses the httpOptions argument to pass a request query string that filters the results for a matching technician.

service.get('/mobile/custom/incidentreport/incidents',
function (req, res) {
    httpOptions={};
    httpOptions.qs = {technician : 'jwhite'};
    req.oracleMobile.database.getAll(
      'FIF_Incidents', {}, httpOptions).then(    
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });
database.insert(table, object, options, httpOptions)

This method lets you add one or more rows to a table.

When the Database_CreateTablesPolicy environment policy is allow, then the following actions can occur:

  • If the table doesn't exist, then it is created.

  • If a column doesn’t exist, then the table is altered to include it.

  • If the value is larger than the column size, then the column is resized.

Ask your mobile cloud administrator about the Database_CreateTablesPolicy environment policy setting.

Arguments

table: Required. String. The name of the database table to add the row to.

object: Required. JSON object containing the table data. If you’re adding one row, then you can use this format:

{ 
  status : 'Open',
  code : '3'
}

If you’re adding multiple rows, then use this format:

[
    {
        status:'Open',
        code:3},
    {
        status:'Completed',
        code:9}
]

options: Optional. JSON object. This object can have the following properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the table, extraFields, and primaryKeys values. This option can be useful for multibyte values. Boolean false
extraFields For an implicit table creation, optionally provide a comma-separated list that specifies which predefined columns to include in the table from amongst id, createdBy, createdOn, modifiedBy, and modifiedOn. For example, createdOn,createdBy.

To not include any predefined columns, specify none.

String To include all the predefined columns, do not include this property. Note that the id column is added to the table automatically if both the primaryKeys and extraFields properties are absent.
primaryKeys For an implicit table creation, provide a URL-encoded, comma-separated list specifying which attributes of the JSON object in the request body constitute the table's primary key. For example, lastName,firstName.

Note:

Because you can’t retrieve the primary key order from the table metadata, make sure that you document the order of the primary fields.
String If you do not specify a primary key, then the service adds an id column to the table, and generates the column's values automatically, as long as you don’t also include extraFields without id in the list.

Response

The response body is a JSON object. If the table is indexed on id, then the response is an array of the new rows’ id values. Otherwise, the response is the rowCount of the records added.

Examples

Here’s an example of calling the method to add two rows. If the table doesn’t exist, then the service creates it. This table doesn’t have extra fields, and its primary key is code:

service.post('/mobile/custom/incidentreport/initStatus', function (req, res) {
  req.oracleMobile.database.insert(
    'FIF_Status',
    [
      {
        status: 'Closed',
        code: '0'},
      {
        status: 'Completed',
        code: '9'}
    ],
    {extraFields: 'none', primaryKeys: 'code'}).then(
    function (result) {
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      res.status(error.statusCode).send(error.error);
    }
  );
});

Here’s an example of the response for this request.

{
  "rowCount": 2
}

Note that if a table’s row key is the system-defined id column (instead of user-defined primary keys), then the response shows the id values for the new rows. For example:

{"items":[{"id":42},{"id":43}]} 
database.merge(table, object, options, httpOptions)

This method lets you add or update rows in a table. Whether the operation performs an add or update depends on whether the table uses id or primary key fields to uniquely identify rows.

  • id field: If you include an id property in the table data in the object argument, then the operation performs an update. Otherwise it adds the row.

  • Primary key fields: If the table uses primary key fields, then the operation performs an update if a row exists with matching primary key values. Otherwise, it adds the row.

Note that if you submit a batch of rows, all the rows must have the same set of columns.

When the Database_CreateTablesPolicy environment policy is allow, then the following actions can occur:

  • If the table doesn't exist, then it is created.

  • If a column doesn’t exist, then the table is altered to include it.

  • If the value is larger than the column size, then the column is resized.

Ask your mobile cloud administrator about the Database_CreateTablesPolicy environment policy setting.

Arguments

table: Required. String. The name of the database table to add the row to.

object: Required. JSON object containing the table data. If you’re adding one row, then you can use this format:

{ 
  status : 'Open',
  code : '3'
}

If you’re adding multiple rows, then use this format:

[
    {
        status:'Open',
        code:'3'},
    {
        status:'Completed',
        code:'9'}
]

options: Optional. JSON object. This object can have the following properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the table, extraFields, and primaryKeys values. This option can be useful for multibyte values. Boolean false
extraFields For an implicit table creation, optionally provide a comma-separated list that specifies which predefined columns to include in the table from amongst id, createdBy, createdOn, modifiedBy, and modifiedOn. For example, createdOn,createdBy.

To not include any predefined columns, specify none.

String To include all the predefined columns, do not include this property. Note that the id column is added to the table automatically if both the primaryKeys and extraFields properties are absent.
primaryKeys For an implicit table creation, provide a URL-encoded, comma-separated list specifying which attributes of the JSON object in the request body constitute the table's primary key. For example, lastName,firstName.

Note:

Because you can’t retrieve the primary key order from the table metadata, make sure that you document the order of the primary fields.
String If you do not specify a primary key, then the operation adds an id column to the table, and generates the column's values automatically, as long as you don’t also include extraFields without id in the list.

Response

The response body is a JSON object. If the table is indexed on id, then the response is an array of the new rows’ id values. Otherwise, the response is the rowCount.

Examples

Here’s an example of calling the method to add or update two rows. If the table doesn’t exist, then the operation creates it. This table doesn’t have extra fields, and its primary key is code:

service.post('/mobile/custom/incidentreport/initStatus', function (req, res) {
  req.oracleMobile.database.merge(
    'FIF_Status',
    [
      {
        status: 'Closed',
        code: '0'},
      {
        status: 'Completed',
        code: '9'}
    ],
    {extraFields: 'none', primaryKeys: 'code'}).then(
    function (result) {
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      res.status(error.statusCode).send(error.error);
    }
  );
});

Here’s an example of the response for this request.

{
  "rowCount": 2
}

Note that if a table’s row key is the system-defined id column (instead of user-defined primary keys), then the response shows the id values for the new rows. For example:

{"items":[{"id":42},{"id":43}]} 

Accessing the Devices API from Custom Code

Use this API to configure which devices that are running a mobile app can receive notifications.

This API has the following methods:

devices.deregister(device, httpOptions)

Call this method to deregister a a mobile client instance that no longer needs to receive notifications.

Arguments

device: Required. JSON object that follows the root (mobile client instance) request schema that’s shown for the POST /mobile/platform/devices/deregister operation in REST APIs for Oracle Mobile Cloud Service.

If the notificationProvider property isn't provided, then the service assumes APNS for iOS, GCM for Android, and WNS for Windows.

Examples

Here’s an example of calling this method to deregister a device.

service.post(
  '/mobile/custom/incidentreport/devices/deregister',
  function (req, res) {
    req.oracleMobile.devices.deregister(
      {
        "notificationToken": "b14d6dfbd9d56e09f098",
        "notificationProvider: "APNS",
        "mobileClient": {
          "id": "my.app.id",
          "platform": "IOS"
        }
      }
    ).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });
devices.register(device, httpOptions)

Call this method to register a new device.

Arguments

device: Required. JSON object that follows the root (mobile client instance) request schema that’s shown for the POST /mobile/platform/devices/register operation in REST APIs for Oracle Mobile Cloud Service.

Response

The response body is a JSON object that follows the root (mobile client instance) response schema that’s shown for the POST /mobile/platform/devices/register operation in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling this method to register a device.

service.post(
  '/mobile/custom/incidentreport/devices/register',
  function (req, res) {
    req.oracleMobile.devices.register(
      {
        "notificationToken": "b14d6dfbd9d56e09f098",
        "notificationProvider: "APNS",
        "mobileClient": {
          "id": "my.app.id",
          "version": "1.0",
          "platform": "IOS"
        }
      }
    ).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response body:

{
  "id": "27fee547-bdd0-4688-9497-475ec5ed0dfd",
  "notificationToken": "b14d6dfbd9d56e09f098",
  "notificationProvider: "APNS",
  "mobileClient": {
    "id": "my.app.id",
    "user": "joe",
    "version": "1.0",
    "platform": "IOS"
  },
  "modifiedOn": "2015-06-17T18:37:59.424Z"
}

Accessing the Location API from Custom Code

The Location API lets you query about location devices, their assets, and the places where they’re located.

This API has the following methods:

You can learn about location devices, assets, and places in Location.

See Accessing the Location Management API from Custom Code for the methods to add, delete, and update assets, devices, and places.

location.assets.getAsset(id, httpOptions)

Call this method to retrieve the asset that matches the specified ID or name.

Arguments

id: Required. Must be one of the following:

  • String that contains the ID of the asset to retrieve.

  • JSON object that contains either the id property or the name property, where the property value indicates the search value. If the object contains both properties, then the SDK retrieves the asset with the matching name.

Response

The response body is a JSON object that follows the Asset schema that is shown for the GET /mobile/platform/location/assets and GET /mobile/platform/location/assets/{id} operations in REST APIs for Oracle Mobile Cloud Service

Examples

Here’s an example of calling this method to retrieve an asset by ID.

service.get(
  '/mobile/custom/incidentreport/assets/:id',
  function (req, res) {
    req.oracleMobile.location.assets.getAsset(req.params.id).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of calling this method to retrieve an asset by name.

service.get(
  '/mobile/custom/incidentreport/assets/:name',
  function (req, res) {
    req.oracleMobile.location.assets.getAsset({name:req.params.name}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response body:

{
   "id":111,
   "createdOn":"2015-08-06T18:37:59.424Z",
   "createdBy":"jdoe",
   "modifiedOn":"2015-08-06T18:37:59.424Z",
   "modifiedBy":"jdoe",
   "name":"RC_WH_01_F01_B023",
   "label":"forklift",
   "description":"Forklift in the FixItFast Warehouse in Redwood City",
   "lastKnownLocation":{
      "gpsPoint":{
         "latitude":37.5548,
         "longitude":-121.1566
      }
   },
   "devices":[
      {
         "id":345,
         "createdOn":"2015-08-06T18:37:59.424Z",
         "createdBy":"jdoe",
         "modifiedOn":"2015-08-08T07:22:44.654Z",
         "modifiedBy":"tsmith",
         "name":"RC_WH_01_F01_B001",
         "description":"Beacon in FixitFast Warehouse in Redwood City",
         "beacon":{
            "iBeacon":{
               "uuid":"B9407F30-F5F8-466E-AFF9-25556B57FE6D",
               "major":"1.0",
               "minor":"1.1"
            }
         },
         "attributes":{
            "manufacturer":"Abc Company",
            "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
            "status":"Active",
            "visibility":"Public"
         },
         "links":[
            {
               "rel":"canonical",
               "href":"/mobile/platform/location/devices/345"
            },
            {
               "rel":"self",
               "href":"/mobile/platform/location/devices/345"
            }
         ]
      }
   ],
   "attributes":{
      "EquipmentManufacturer":"Abc Company",
      "beaconID":"AE2924505-66045"
   },
   "links":[
      {
         "rel":"canonical",
         "href":"/mobile/platform/location/assets/111"
      },
      {
         "rel":"self",
         "href":"/mobile/platform/location/assets/111"
      }
   ]
}
location.assets.query(queryObject, httpOptions)

Call this method to retrieve the assets that match the query parameters that you specify in queryObject.

Arguments

queryObject: Required. String. The parameters that describe the desired results. For details, see the body parameter for the POST /mobile/platform/location/assets/query operation in REST APIs for Oracle Mobile Cloud Service. If you don’t have any query parameters, then use an empty body ({}).

Response

The response body is a JSON object that contains an array of items that follow the Asset schema that is shown for the POST /mobile/platform/location/assets/query operation in REST APIs for Oracle Mobile Cloud Service. The result also contains paging information. For example:

"totalResults":2,
"offset":0,
"limit":40,
"count":2,
"hasMore":false

Examples

Here’s an example of calling this method. It returns all assets that have the string 1225 in the name or description (case-insensitive).
service.get(
  '/mobile/custom/incidentreport/assets,
  function (req, res) {
    req.oracleMobile.location.assets.query({"search":"1225"}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });
Here’s an example of the response body:
{
    "items":[
        {
            "devices":[
                {
                    "id":3401,
                    "createdBy":"jdoe",
                    "name":"RC_WH_01_F01_B001",
                    "createdOn":"2015-08-06T18:37:59.424Z",
                    "modifiedOn":"2015-08-08T07:22:44.654Z",
                    "beacon":{
                        "iBeacon":{
                            "uuid":"B9407F30-F5F8-466E-AFF9-25556B57FE6D",
                            "major":"1.0",
                            "minor":"1.1"}},
                    "modifiedBy":"tsmith",
                    "links":[
                        {
                            "rel":"canonical",
                            "href":"/mobile/platform/location/devices/3401"},
                        {
                            "rel":"self",
                            "href":"/mobile/platform/location/devices/3401"}
                    ],
                    "attributes":{
                        "manufacturer":"Example Company",
                        "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                        "status":"Active",
                        "visibility":"Public"},
                    "description":"Beacon on 1st Floor in FixitFast Warehouse in Redwood City"}
            ],
            "label":"hospital bed",
            "lastKnownLocation":{
                "placeId":244},
            "id":333,
            "createdBy":"jdoe",
            "name":"hospital bed #233",
            "createdOn":"2015-08-06T18:37:59.424Z",
            "modifiedOn":"2015-08-06T18:37:59.424Z",
            "modifiedBy":"jdoe",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/location/assets/333"},
                {
                    "rel":"self",
                    "href":"/mobile/platform/location/assets/333"}
            ],
            "attributes":{
                "EquipmentManufacturer":"Example Company",
                "SJId":"6754843090"},
            "description":"model 1225 hospital bed"},
        {
            "devices":[
                {
                    "id":648,
                    "createdBy":"jdoe",
                    "name":"RC_WH_01_F01_B001",
                    "createdOn":"2015-08-06T18:37:59.424Z",
                    "modifiedOn":"2015-08-08T07:22:44.654Z",
                    "beacon":{
                        "iBeacon":{
                            "uuid":"B9407F30-F5F8-466E-AFF9-25556B57FE6D",
                            "major":"1.0",
                            "minor":"1.1"}},
                    "modifiedBy":"tsmith",
                    "links":[
                        {
                            "rel":"canonical",
                            "href":"/mobile/platform/location/devices/648"},
                        {
                            "rel":"self",
                            "href":"/mobile/platform/location/devices/648"}
                    ],
                    "attributes":{
                        "manufacturer":"Example Company",
                        "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                        "status":"Active",
                        "visibility":"Public"},
                    "description":"Beacon on 1st Floor in FixitFast Warehouse in Redwood City"}
            ],
            "label":"hospital bed",
            "lastKnownLocation":{
                "placeId":360},
            "id":888,
            "createdBy":"jdoe",
            "name":"hospital bed #233",
            "createdOn":"2015-10-16T09:24:41.354Z",
            "modifiedOn":"2015-10-16T09:24:41.354Z",
            "modifiedBy":"jdoe",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/location/assets/888"},
                {
                    "rel":"self",
                    "href":"/mobile/platform/location/assets/888"}
            ],
            "attributes":{
                "EquipmentManufacturer":"Example Company",
                "SJId":"6754843090"},
            "description":"model 1225 hospital bed"}
    ],
    "totalResults":2,
    "offset":0,
    "count":2,
    "hasMore":false
}
location.devices.getDevice(id, httpOptions)

Call this method to retrieve the device that matches the specified ID or name.

Arguments

id: Required. Must be one of the following:

  • String that contains the ID of the device to retrieve.

  • JSON object that contains either the id property or the name property, where the property value indicates the search value. If the object contains both properties, then the SDK retrieves the device with the matching name.

Response

The response body is a JSON object that follows the Location device schema that is shown for the GET /mobile/platform/location/devices and GET /mobile/platform/location/devices/{id} operations in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling this method to retrieve a device by ID.

service.get(
  '/mobile/custom/incidentreport/devices/:id',
  function (req, res) {
    req.oracleMobile.location.devices.getDevice(req.params.id).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of calling this method to retrieve a device by name.

service.get(
  '/mobile/custom/incidentreport/devices/:name',
  function (req, res) {
    req.oracleMobile.location.devices.getDevice({name:req.params.name}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response body:

{
  "id": 12345,
  "createdOn": "2015-08-06T18:37:59.424Z",
  "createdBy": "jdoe",
  "modifiedOn": "2015-08-08T07:22:44.654Z",
  "modifiedBy": "tsmith",
  "name": "RC_WH_01_F01_B001",
  "description": "Beacon on 1st Floor in FixitFast Warehouse in Redwood City",
  "place":
  {
    "id": 111,
    "createdOn": "2015-08-06T18:37:59.424Z",
    "createdBy": "jdoe",
    "modifiedOn": "2015-08-06T18:37:59.424Z",
    "modifiedBy": "jdoe",
    "name": "FixitFast Redwood City Warehouse",
    "label": "FixitFast Warehouse",
    "parentPlace": 42,
    "description": "FixitFast Warehouse in Redwood City",
    "address" : {
      "gpsPoint" : {
        "latitude": 37.5548,
        "longitude": -121.1566
      }
    },
    "attributes" : {
      "equipmentManufacturer": "Abc Corp"
    },
    "links": [
      {
        "rel": "canonical",
        "href": "/mobile/platform/location/places/111"
      },
      {
        "rel": "self",
        "href": "/mobile/platform/location/places/111"
      }
    ]
  },
  "beacon": {
    "iBeacon" : {
      "uuid": "B9407F30-F5F8-466E-AFF9-25556B57FE6D",
      "major": "1.0",
      "minor": "1.1"
    }
  },
  "attributes" : {
    "manufacturer": "Abc Company",  
    "manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D"
    "status": "Active",
    "visibility": "Public"
  },
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/platform/location/devices/12345"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/location/devices/12345"
    }
  ]
} 
location.devices.query(queryObject, httpOptions)

Call this method to retrieve the devices that match the query parameters that you specify in queryObject.

Arguments

queryObject: Required. String. The parameters that describe the desired results. For details, see the body parameter for the POST /mobile/platform/location/devices/query operation in REST APIs for Oracle Mobile Cloud Service. If you don’t have any query parameters, then use an empty body ({}).

Response

The response body is a JSON object that contains an array of items that follow the Location device schema that is shown for the POST /mobile/platform/location/devices/query operation in REST APIs for Oracle Mobile Cloud Service The result also contains paging information. For example:

"totalResults":2,
"offset":0,
"limit":40,
"count":2,
"hasMore":false

Examples

Here’s an example of calling this method. It returns the devices that have the string warehouse in either the name or description (case-insensitive).
service.get(
  '/mobile/custom/incidentreport/devices,
  function (req, res) {
    req.oracleMobile.location.devices.query({{ "search": "Warehouse"}}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });
Here’s an example of the response body:
{
    "items":[
        {
            "id":33,
            "name":"RC_WH_01_B09_C004",
            "description":"Beacon on 2nd Floor NW in FixItFast Warehouse in Redwood City",
            "protocol":"altBeacon"},
        {
            "id":12,
            "name":"RC_WH_01_F01_B001",
            "description":"Beacon on 1st Floor SE in FixItFast Warehouse in Redwood City",
            "protocol":"altBeacon"},
        {
            "id":61,
            "name":"RC_WH_01_F01_B008",
            "description":"Beacon on 2nd Floor SW in FixItFast Warehouse in Redwood City",
            "protocol":"altBeacon"},
        {
            "id":58,
            "name":"RC_WH_02_F01_B011",
            "description":"Beacon on 1st Floor NW in FixitFast Warehouse in Redwood City",
            "protocol":"altBeacon"},
        {
            "id":114,
            "name":"RC_WH_01_K22_A999",
            "description":"Beacon on 3rd Floor NW in FixitFast Warehouse in Redwood City",
            "protocol":"altBeacon"}
    ],
    "totalResults":5,
    "offset":0,
    "count":5,
    "hasMore":false
}
location.places.getPlace(id, httpOptions)

Call this method to retrieve the place that matches the specified ID or name.

Arguments

id: Required. Must be one of the following:

  • String that contains the ID of the place to retrieve.

  • JSON object that contains either the id property or the name property, where the property value indicates the search value. If the object contains both properties, then the SDK retrieves the place with the matching name.

Response

The response body is a JSON object that follows the Place schema that is shown for the GET /mobile/platform/location/places and GET /mobile/platform/location/places/{id} operations in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling this method to retrieve a place by ID.

service.get(
  '/mobile/custom/incidentreport/places/:id',
  function (req, res) {
    req.oracleMobile.location.places.getPlace(req.params.id).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of calling this method to retrieve a place by name.

service.get(
  '/mobile/custom/incidentreport/places/:name',
  function (req, res) {
    req.oracleMobile.location.places.getPlace({name:req.params.name}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response body:

{
  "id": 111,
  "createdOn": "2015-08-06T18:37:59.424Z",
  "createdBy": "jdoe",
  "modifiedOn": "2015-08-06T18:37:59.424Z",
  "modifiedBy": "jdoe",
  "name": "FixitFast Redwood City Warehouse",
  "label": "FixitFast Warehouse",
  "parentPlace": 42,
  "description": "FixitFast Warehouse in Redwood City",
  "address" : {
    "gpsPoint" : {
      "latitude": 37.5548,
      "longitude": -121.1566
    }
  },
  "attributes" : {
    "equipmentManufacturer": "Abc Corp"
  },
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/platform/location/places/111"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/location/places/111"
    }
  ]
}  
location.places.query(queryObject, httpOptions)

Call this method to retrieve the places and, optionally, the associated devices that match the query properties that you specify in the queryObject.

Arguments

queryObject: Required. String. The parameters that describe the desired results. For details, see the body parameter for the POST /mobile/platform/location/places/query operation in REST APIs for Oracle Mobile Cloud Service. If you don’t have any query parameters, then use an empty body ({}).

Response

The response body is a JSON object that contains an array of items that follow the Place schema that is shown for the POST /mobile/platform/location/places/query operation in REST APIs for Oracle Mobile Cloud Service. The result also contains paging information. For example:
"totalResults":2,
"offset":0,
"limit":40,
"count":2,
"hasMore":false

Examples

Here’s an example of calling this method. It returns all places that have the string warehouse in the name or description (case-insensitive). By default, the response includes the children array, which contains information about descendent places. In this request, the includeDescendantsInResult property is set to none. Therefore the request doesn't include that array.
service.get(
  '/mobile/custom/incidentreport/places',
  function (req, res) {
    req.oracleMobile.location.places.query({"search":"warehouse","includeDescendantsInResult":"none" }).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response body:

{
    "items":[
        {
            "devices":[
                {
                    "id":12345,
                    "createdBy":"jdoe",
                    "name":"RC_WH_01_F01_B001",
                    "createdOn":"2015-08-06T18:37:59.424Z",
                    "modifiedOn":"2015-08-08T07:22:44.654Z",
                    "beacon":{
                        "iBeacon":{
                            "uuid":"B9407F30-F5F8-466E-AFF9-25556B57FE6D",
                            "major":"1.0",
                            "minor":"1.1"}},
                    "modifiedBy":"tsmith",
                    "links":[
                        {
                            "rel":"canonical",
                            "href":"/mobile/platform/location/devices/12345"},
                        {
                            "rel":"self",
                            "href":"/mobile/platform/location/devices/12345"}
                    ],
                    "attributes":{
                        "manufacturer":"Abc Company",
                        "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                        "status":"Active",
                        "visibility":"Public"},
                    "description":"Beacon on 1st Floor in FixitFast Warehouse in Redwood City"}
            ],
            "label":"FixItFast Warehouse",
            "id":112,
            "createdBy":"jdoe",
            "name":"FixItFast Redwood City Warehouse",
            "createdOn":"2015-08-06T18:37:59.424Z",
            "modifiedOn":"2015-08-06T18:37:59.424Z",
            "address":{
                "gpsPoint":{
                    "latitude":122,
                    "longitude":37}},
            "modifiedBy":"jdoe",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/location/places/112"},
                {
                    "rel":"self",
                    "href":"/mobile/platform/location/places/112"}
            ],
            "attributes":{
                "hours":"9am-6pm"},
            "hasChildren":false,
            "parentPlace":42,
            "description":"FixItFast Warehouse in Redwood City"},
        {
            "devices":[
                {
                    "id":111,
                    "createdBy":"jdoe",
                    "name":"RC_WH_01_F01_B001",
                    "createdOn":"2015-08-06T18:37:59.424Z",
                    "modifiedOn":"2015-08-08T07:22:44.654Z",
                    "beacon":{
                        "iBeacon":{
                            "uuid":"B9407F30-F5F8-466E-AFF9-25556B57FE6D",
                            "major":"1.0",
                            "minor":"1.1"}},
                    "modifiedBy":"tsmith",
                    "links":[
                        {
                            "rel":"canonical",
                            "href":"/mobile/platform/location/devices/111"},
                        {
                            "rel":"self",
                            "href":"/mobile/platform/location/devices/111"}
                    ],
                    "attributes":{
                        "manufacturer":"Abc Company",
                        "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                        "status":"Active",
                        "visibility":"Public"},
                    "description":"Beacon on 1st Floor in FixitFast Warehouse in Redwood City"},
                {
                    "id":222,
                    "createdBy":"jdoe",
                    "name":"RC_WH_01_F01_B996",
                    "createdOn":"2015-08-08T18:37:59.424Z",
                    "modifiedOn":"2015-08-12T07:22:44.654Z",
                    "beacon":{
                        "iBeacon":{
                            "uuid":"B9407F30-F5F8-466E-AFF9-25552345908234DD0",
                            "major":"1.0",
                            "minor":"1.1"}},
                    "modifiedBy":"tsmith",
                    "links":[
                        {
                            "rel":"canonical",
                            "href":"/mobile/platform/location/devices/222"},
                        {
                            "rel":"self",
                            "href":"/mobile/platform/location/devices/222"}
                    ],
                    "attributes":{
                        "manufacturer":"Abc Company",
                        "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                        "status":"Active",
                        "visibility":"Public"},
                    "description":"Beacon on 2nd Floor in FixitFast Warehouse in Redwood City"}
            ],
            "label":"FixItFast Warehouse",
            "id":325,
            "createdBy":"jdoe",
            "name":"FixItFast Palo Alto Warehouse",
            "createdOn":"2015-08-06T19:27:59.424Z",
            "modifiedOn":"2015-08-06T19:27:59.424Z",
            "address":{
                "gpsCircle":{
                    "latitude":123,
                    "longitude":37,
                    "radius":300}},
            "modifiedBy":"jdoe",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/location/places/325"},
                {
                    "rel":"self",
                    "href":"/mobile/platform/location/places/325"}
            ],
            "attributes":{
                "hours":"9am-6pm"},
            "hasChildren":false,
            "parentPlace":42,
            "description":"FixItFast Warehouse in Palo Alto"}
    ],
    "totalResults":2,
    "offset":0,
    "count":2,
    "hasMore":false
}

Accessing the Location Management API from Custom Code

The Location Management API lets you create, update, and delete location devices, places, and assets.

You can learn about location devices, assets, and places in Location.

The Authorization request header for these methods must use OAUTH. Otherwise the methods return a 404 HTTP status code.

This API has the following methods:

For methods to query and retrieve information about assets, devices, and places, see Accessing the Location API from Custom Code.

Location Management Context Argument

All the Location Management API methods require a context argument, which is a JSON object with the following properties. This information is required to get authorization to manage location information. In addition, the mobile app must use OAuth authorization.

Note that the custom code can call mbe.getMBE() to get the mobile backend information.

Property Desc Type
mbe The name of the mobile backend. String
username The name of a user who is an MCS team member and has the MobileEnvironment_System role. Team members and their roles are managed from Oracle Cloud Infrastructure Classic Console. SeeAssign MCS Team Member Roles. String
version The version of the mobile backend. String

Note:

If the Authorization request header doesn’t use OAuth, then the methods return 404. If the username is not an MCS team member who has the MobileEnvironment_System role, then the methods return 403.
location.assets.register(assets, context, httpOptions)

This method lets you create one or more assets.

Arguments

assets: Required. JSON object that follows the request root schema (Assets Array) that is shown for the POST /mobile/system/locationManagement/assets operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
  "items":[
      {
          "name":"hospital bed #233",
          "label":"hospital bed",
          "description":"model 1225 hospital bed",
          "lastKnownLocation":{
              "placeId":244
          },
          "devices":[
              1111
          ],
          "attributes":{
              "EquipmentManufacturer":"Example Company",
              "SJId":"6754843090"
          }
      }
  ]
}

context: Required. JSON object as described in Location Management Context Argument.

Response

The response body, which shows the stored assets, is a JSON object that follows the response root schema (Assets Array) that is shown for the POST /mobile/system/locationManagement/assets operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request body would look like this:
{
  "userName":"anAdministrator",
  "assets": {
    "items":[
      {
        "name":"hospital bed #233",
        "label":"hospital bed",
        "description":"model 1225 hospital bed",
        "attributes":{
          "EquipmentManufacturer":"Example Company",
          "SJId":"6754843090"
        }
      }
    ]
  }
}

This example puts the username in the context object and passes assets as the request body.

service.post('/mobile/custom/incidentreport/assets', function (req, res) {
  req.oracleMobile.location.assets.register(
    req.body.assets, 
    {
      username: req.body.userName, 
      mbe: req.oracleMobile.mbe.getMBE().name, 
      version: req.oracleMobile.mbe.getMBE().version
    }).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.sta).send(sCode, error.error);
    }
  );
});

Here’s an example of the response body.

{
  "items": [
    {
      "id": 12,
      "createdOn": "2016-11-05T02:33:36.154Z",
      "createdBy": "anAdministrator",
      "modifiedOn": "2016-11-05T02:33:36.154Z",
      "modifiedBy": "anAdministrator",
      "name": "hospital bed #233",
      "label": "hospital bed",
      "description": "model 1225 hospital bed",
      "lastKnownLocation": null,
      "attributes": {
        "EquipmentManufacturer": "Example Company",
        "SJId": "6754843090"
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/assets/12"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/assets/12"
        }
      ]
    }
  ]
}
location.assets.remove(id, context, httpOptions)

Use this method to delete assets.

Arguments

id: Required. IDs of the assets to remove. This argument can be either a single value or an array of values.

context: Required. JSON object as described in Location Management Context Argument.

Response

If you provide a single value, then the service doesn’t return a response body. The status code is 204 if the asset was deleted and 404 if it doesn’t exist.

If you provide an array of IDs, then the status code is 200 for a successful request. The response contains a batch object with an array of responses for the individual delete requests. For schema details, see the Delete Multiple Assets operation in REST APIs for Oracle Mobile Cloud Service.

Here’s an example:

{
    "batch":[
        {
            "body":{
                "id":353,
                "message":"asset was deleted successfully."},
            "code":200},
        {
            "body":{
                "id":354,
                "message":"asset was deleted successfully."},
            "code":200},
        {
            "body":{
                "id":355,
                "message":"asset not found."},
            "code":404}
    ]
}

Examples

In this example, if the id query parameter contains multiple IDs, then it converts the query string into an array.

Note that the user name of the user who has the MobileEnvironment_System role is passed in the user query parameter.

service.delete('/mobile/custom/location/assets', function(req,res) {
  var contextObject = {
    username: req.query.user,
    mbe: req.oracleMobile.mbe.getMBE().name,
    version: req.oracleMobile.mbe.getMBE().version
  };
  var id = req.query.id.split(',');
  if (id.length == 0){
      id = req.query.id;
  }
  req.oracleMobile.location.assets.remove(
      id,
      contextObject
    ).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});
location.assets.update(id, asset, context, httpOptions)

This method lets you update an asset.

Arguments

id: Required. The ID of the asset. This ID must be an existing asset ID.

asset: Required. JSON object that follows the request root schema (Asset) that is shown for the PUT /mobile/system/locationManagement/assets/{id} operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
    "lastKnownLocation":{
        "gpsPoint":{
            "latitude":37.5548,
            "longitude":-121.1566
        }
    },
    "devices":[
        11
    ]
}

context: Required. JSON object as described in Location Management Context Argument.

Response

The response body, which shows the updated asset, is a JSON object that follows the response root schema (Asset) that is shown for the PUT /mobile/system/locationManagement/assets/{id} operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request body would look like this:
{
   "userName":"anAdministrator",
   "asset":{
      "lastKnownLocation":{
         "gpsPoint":{
            "latitude":37.5548,
            "longitude":-121.1566
         }
      },
      "devices":[
         11
      ]
   }
}

This example puts the username in the context object and passes asset as the request body.

service.put('/mobile/custom/incidentreport/assets/:id', function (req, res) {
  req.oracleMobile.location.assets.update(
    req.params.id,
    req.body.asset, 
    {
      username: req.body.userName, 
      mbe: req.oracleMobile.mbe.getMBE().name, 
      version: req.oracleMobile.mbe.getMBE().version
    }).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});    

Here’s an example of the response body.

{
  "id": 11,
  "createdOn": "2016-11-08T21:26:38.318Z",
  "createdBy": "anAdministrator",
  "modifiedOn": "2016-11-08T22:18:24.157Z",
  "modifiedBy": "anAdministrator",
  "name": "hospital bed #233",
  "label": "hospital bed",
  "description": "model 1225 hospital bed",
  "lastKnownLocation": {
    "gpsPoint": {
      "longitude": -121.1566,
      "latitude": 37.5548
    }
  },
  "devices": [
    {
      "id": 11,
      "createdOn": "2016-11-08T18:01:18.531Z",
      "createdBy": "anAdministrator",
      "modifiedOn": "2016-11-08T18:01:18.531Z",
      "modifiedBy": "anAdministrator",
      "name": "RC_WH_01_F01_B016",
      "description": "Beacon on 2nd Floor in FixitFast Warehouse in Redwood City",
      "beacon": {
        "altBeacon": {
          "id1": "B9407F30-F5F8-466E",
          "id2": "AFF9",
          "id3": "25556B57FE6D"
        }
      },
      "attributes": {
        "manufacturer": "Abc Company",
        "status": "Active",
        "manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D",
        "visibility": "Public"
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/devices/11"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/devices/11"
        }
      ]
    }
  ],
  "attributes": {
    "EquipmentManufacturer": "Example Company",
    "SJId": "6754843090"
  },
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/platform/location/assets/11"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/location/assets/11"
    }
  ]
}
location.devices.register(devices, context, httpOptions)

This method lets you create one or more devices.

Arguments

devices: Required. JSON object that follows the request root schema (Devices Array) that is shown for the POST /mobile/system/locationManagement/devices operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
    "items":[
        {
            "name":"RC_WH_01_F01_B006",
            "description":"Beacon on 2nd Floor in FixitFast Warehouse in Redwood City",
            "asset":333,
            "beacon":{
                "altBeacon":{
                    "id1":"B9407F30-F5F8-466E",
                    "id2":"AFF9",
                    "id3":"25556B57FE6D"
                }
            },
            "attributes":{
                "manufacturer":"Abc Company",
                "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                "status":"Active",
                "visibility":"Public"
            }
        }
    ]
}

context: Required. JSON object as described in Location Management Context Argument.

Response

The response body, which shows the stored devices, is a JSON object that follows the response root schema (Devices Array) that is shown for the POST /mobile/system/locationManagement/devices operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request body would look like this:
{
  "userName":"anAdministrator",
  "devices": {
    "items":[
       {
         "name":"RC_WH_01_F01_B006",
         "description":"Beacon on 2nd Floor in FixitFast Warehouse in Redwood City",
            "beacon":{
                "altBeacon":{
                    "id1":"B9407F30-F5F8-466E",
                    "id2":"AFF9",
                    "id3":"25556B57FE6D"
                }
            },
            "attributes":{
                "manufacturer":"Abc Company",
                "manufacturerId":"10D39AE7-020E-4467-9CB2-DD36366F899D",
                "status":"Active",
                "visibility":"Public"
            }
        }
    ]
  }
}

This example puts the username in the context object and passes devices as the request body.

service.post('/mobile/custom/incidentreport/devices, function (req, res) {
  req.oracleMobile.location.devices.register(
    req.body.devices, 
    {
      username: req.body.userName, 
      mbe: req.oracleMobile.mbe.getMBE().name, 
      version: req.oracleMobile.mbe.getMBE().version
    }).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});

Here’s an example of the response body.

{
  "items": [
    {
      "id": 10,
      "createdOn": "2016-11-08T15:54:51.603Z",
      "createdBy": "anAdministrator",
      "modifiedOn": "2016-11-08T15:54:51.603Z",
      "modifiedBy": "anAdministrator",
      "name": "RC_WH_01_F01_B006",
      "description": "Beacon on 2nd Floor in FixitFast Warehouse in Redwood City",
      "beacon": {
        "altBeacon": {
          "id1": "B9407F30-F5F8-466E",
          "id2": "AFF9",
          "id3": "25556B57FE6D"
        }
      },
      "attributes": {
        "manufacturer": "Abc Company",
        "manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D",
        "status": "Active",
        "visibility": "Public"
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/devices/10"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/devices/10"
        }
      ]
    }
  ]
}
location.devices.remove(id, context, httpOptions)

Use this method to delete devices.

Arguments

id: Required. IDs of the devices to remove. This argument can be either a single value or an array of values.

context: Required. JSON object as described in Location Management Context Argument.

Response

If you provide a single value, then the service doesn’t return a response body. The status code is 204 if the device was deleted and 404 if it doesn’t exist.

If you provide an array of IDs, then the status code is 200 for a successful request. The response contains a batch object with an array of responses for the individual delete requests. For schema details, see the Delete Multiple Devices operation in REST APIs for Oracle Mobile Cloud Service.

Here’s an example:

{
    "batch":[
        {
            "code":200,
            "body":{
                "id":121,
                "message":"device was deleted successfully."
            }
        },
        {
            "code":200,
            "body":{
                "id":122,
                "message":"device was deleted successfully."
            }
        },
        {
            "code":404,
            "body":{
                "id":123,
                "message":"device not found."
            }
        }
    ]
}

Examples

In this example, if the id query parameter contains multiple IDs, then it converts the query string into an array.

Note that the user name of the user who has the MobileEnvironment_System role is passed in the user query parameter.

service.delete('/mobile/custom/location/devices', function(req,res) {
  var contextObject = {
    username: req.query.user,
    mbe: req.oracleMobile.mbe.getMBE().name,
    version: req.oracleMobile.mbe.getMBE().version
  };
  var id = req.query.id.split(',');
  if (id.length == 0){
      id = req.query.id;
  }
  req.oracleMobile.location.devices.remove(
      id,
      contextObject
    ).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});
location.devices.update(id, device, context, httpOptions)

This method lets you update a device.

Arguments

id: Required. The ID of the device. This ID must be an existing device ID.

device: Required. JSON object that follows the request root schema (Device) that is shown for the PUT /mobile/system/locationManagement/device/{id} operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
    "attributes":{
        "status":"Inactive",
        "visibility":"Private"
    }
}

context: Required. JSON object as described in Location Management Context Argument.

Response

The response body, which shows the updated device, is a JSON object that follows the response root schema (Device) that is shown for the PUT /mobile/system/locationManagement/devices/{id} operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request body would look like this:
{
   "userName":"anAdministrator",
   "device":{
      "attributes":{
         "status":"Inactive",
         "visibility":"Private"
      }
   }
}

This example puts the username in the context object and passes device as the request body.

service.put('/mobile/custom/incidentreport/device/:id', function (req, res) {
  req.oracleMobile.location.device.update(
    req.params.id,
    req.body.device, 
    {
      username: req.body.userName, 
      mbe: req.oracleMobile.mbe.getMBE().name, 
      version: req.oracleMobile.mbe.getMBE().version
    }).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});    

Here’s an example of the response body.

{
  "id": 11,
  "createdOn": "2016-11-08T18:01:18.531Z",
  "createdBy": "anAdministrator",
  "modifiedOn": "2016-11-08T22:45:47.545Z",
  "modifiedBy": "anAdministrator",
  "name": "RC_WH_01_F01_B016",
  "description": "Beacon on 2nd Floor in FixitFast Warehouse in Redwood City",
  "asset": {
    "id": 11,
    "createdOn": "2016-11-08T21:26:38.318Z",
    "createdBy": "anAdministrator",
    "modifiedOn": "2016-11-08T22:18:24.157Z",
    "modifiedBy": "anAdministrator",
    "name": "hospital bed #233",
    "label": "hospital bed",
    "description": "model 1225 hospital bed",
    "lastKnownLocation": {
      "gpsPoint": {
        "longitude": -121.1566,
        "latitude": 37.5548
      }
    },
    "attributes": {
      "EquipmentManufacturer": "Example Company",
      "SJId": "6754843090"
    },
    "links": [
      {
        "rel": "canonical",
        "href": "/mobile/platform/location/assets/11"
      },
      {
        "rel": "self",
        "href": "/mobile/platform/location/assets/11"
      }
    ]
  },
  "beacon": {
    "altBeacon": {
      "id1": "B9407F30-F5F8-466E",
      "id2": "AFF9",
      "id3": "25556B57FE6D"
    }
  },
  "attributes": {
    "manufacturer": "Abc Company",
    "status": "Inactive",
    "manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D",
    "visibility": "Private"
  },
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/platform/location/devices/11"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/location/devices/11"
    }
  ]
}
location.places.register(places, context, httpOptions)

This method lets you create one or more places.

Arguments

places: Required. JSON object that follows the request root schema (Places Array) that is shown for the POST /mobile/system/locationManagement/places operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
    "items":[
        {
            "name":"FixItFast Redwood City Warehouse",
            "label":"FixItFast Warehouse",
            "parentPlace":42,
            "description":"FixItFast Warehouse in Redwood City",
            "address":{
                "gpsPoint":{
                    "latitude":122,
                    "longitude":37
                }
            },
            "devices":[
                12345
            ],
            "attributes":{
                "hours":"9am-6pm"
            }
        }
    ]
}

context: Required. JSON object as described in Location Management Context Argument.

Response

The response body, which shows the stored places, is a JSON object that follows the response root schema (Places Array) that is shown for the POST /mobile/system/locationManagement/places operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request body would look like this:
{
  "userName":"anAdministrator",
  "places": {
    "items":[
       {
            "name":"FixItFast Redwood City Warehouse",
            "label":"FixItFast Warehouse",
            "description":"FixItFast Warehouse in Redwood City",
            "address":{
                "gpsPoint":{
                    "latitude":89,
                    "longitude":37
                }
            },
                "attributes":{
                "hours":"9am-6pm"
            }
        }
    ]
  }
}

This example puts the username in the context object and passes places as the request body.

service.post('/mobile/custom/incidentreport/places', function (req, res) {
  req.oracleMobile.location.places.register(
    req.body.places, 
    {
      username: req.body.userName, 
      mbe: req.oracleMobile.mbe.getMBE().name, 
      version: req.oracleMobile.mbe.getMBE().version
    }).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});

Here’s an example of the response body.

{
  "items": [
    {
      "id": 10,
      "createdOn": "2016-11-08T17:55:21.816Z",
      "createdBy": "john.doe",
      "modifiedOn": "2016-11-08T17:55:21.816Z",
      "modifiedBy": "john.doe",
      "name": "FixItFast Redwood City Warehouse",
      "label": "FixItFast Warehouse",
      "description": "FixItFast Warehouse in Redwood City",
      "hasChildren": false,
      "address": {
        "gpsPoint": {
          "longitude": 37,
          "latitude": 89
        }
      },
      "attributes": {
        "hours": "9am-6pm"
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/places/10"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/places/10"
        }
      ]
    }
  ]
}
location.places.remove(id, context, httpOptions)

Use this method to delete places.

Arguments

id: Required. IDs of the places to remove. This argument can be either a single value or an array of values.

context: Required. JSON object as described in Location Management Context Argument.

Response

If you provide a single value, then the service doesn’t return a response body. The status code is 204 if the place was deleted and 404 if it doesn’t exist.

If you provide an array of IDs, then the status code is 200 for a successful request. The response contains a batch object with an array of responses for the individual delete requests. For schema details, see the Delete Multiple Places operation in REST APIs for Oracle Mobile Cloud Service.

Here’s an example:

{
    "batch":[
        {
            "body":{
                "id":222,
                "message":"place was deleted successfully."},
            "code":200},
        {
            "body":{
                "id":223,
                "message":"place was deleted successfully."},
            "code":200},
        {
            "body":{
                "id":224,
                "message":"place not found."},
            "code":404}
    ]
}

Examples

In this example, if the id query parameter contains multiple IDs, then it converts the query string into an array.

Note that the user name of the user who has the MobileEnvironment_System role is passed in the user query parameter.

service.delete('/mobile/custom/location/places, function(req,res) {
  var contextObject = {
    username: req.query.user,
    mbe: req.oracleMobile.mbe.getMBE().name,
    version: req.oracleMobile.mbe.getMBE().version
  };
  var id = req.query.id.split(',');
  if (id.length == 0){
      id = req.query.id;
  }
  req.oracleMobile.location.places.remove(
      id,
      contextObject
    ).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});
location.places.removeCascade(id, context, httpOptions)

Use this method to delete a parent place and all its child places.

Arguments

id: Required. The ID of the place. This ID must be an existing place ID.

context: Required. JSON object as described in Location Management Context Argument.

Examples

In this example, if the cascade query parameter is true, then the method calls removeCascade() instead of remove().

Note that the user name of the user who has the MobileEnvironment_System role is passed in the user query parameter.

service.delete('/mobile/custom/location/places/:id', function(req,res) {
  var contextObject = {
    username: req.query.user,
    mbe: req.oracleMobile.mbe.getMBE().name,
    version: req.oracleMobile.mbe.getMBE().version
  };
  var removeFunc = req.oracleMobile.location.places.remove;
  if (req.query.cascade == 'true') {
      removeFunc = req.oracleMobile.location.places.removeCascade;
  }
  removeFunc(
    req.params.id,
    contextObject
  ).then(
     function (result) {
        res.type('application/json');
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        console.dir(error);
        res.status(error.statusCode).send(error.error);
      }
   )
 });
location.places.update(id, place, context, httpOptions)

This method lets you update a place.

Arguments

id: Required. The ID of the place. This ID must be an existing place ID.

place: Required. JSON object that follows the request root schema (Place) that is shown for the PUT /mobile/system/locationManagement/place/{id} operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
    "address":{
        "gpsPoint":{
            "latitude":-121.1566,
            "longitude":37.5548
        }
    },
    "devices":[
        1111
    ]
}

context: Required. JSON object as described in Location Management Context Argument.

Response

The response body, which shows the updated place, is a JSON object that follows the response root schema (Place) that is shown for the PUT /mobile/system/locationManagement/places/{id} operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request body would look like this:
{
   "userName":"anAdministrator",
   "place":{
      "address":{
         "gpsPoint":{
            "latitude":-89,
            "longitude":37
         }
      },
      "devices":[
         11
      ]
   }
}

This example puts the username in the context object and passes place as the request body.

service.put('/mobile/custom/incidentreport/place/:id', function (req, res) {
  req.oracleMobile.location.place.update(
    req.params.id,
    req.body.place, 
    {
      username: req.body.userName, 
      mbe: req.oracleMobile.mbe.getMBE().name, 
      version: req.oracleMobile.mbe.getMBE().version
    }).then(
    function (result) {
      res.type('application/json');
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      console.dir(error);
      res.status(error.statusCode).send(error.error);
    }
  );
});    

Here’s an example of the response body.

{
  "id": 11,
  "createdOn": "2016-11-08T23:36:55.371Z",
  "createdBy": "anAdministrator",
  "modifiedOn": "2016-11-08T23:37:45.576Z",
  "modifiedBy": "anAdministrator",
  "name": "FixItFast Redwood City Warehouse",
  "label": "FixItFast Warehouse",
  "description": "FixItFast Warehouse in Redwood City",
  "hasChildren": false,
  "address": {
    "gpsPoint": {
      "longitude": 37,
      "latitude": 89
    }
  },
  "devices": [
    {
      "id": 11,
      "createdOn": "2016-11-08T18:01:18.531Z",
      "createdBy": "anAdministrator",
      "modifiedOn": "2016-11-08T22:45:47.545Z",
      "modifiedBy": "anAdministrator",
      "name": "RC_WH_01_F01_B016",
      "description": "Beacon on 2nd Floor in FixitFast Warehouse in Redwood City",
      "beacon": {
        "altBeacon": {
          "id1": "B9407F30-F5F8-466E",
          "id2": "AFF9",
          "id3": "25556B57FE6D"
        }
      },
      "attributes": {
        "manufacturer": "Abc Company",
        "status": "Inactive",
        "manufacturerId": "10D39AE7-020E-4467-9CB2-DD36366F899D",
        "visibility": "Private"
      },
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/platform/location/devices/11"
        },
        {
          "rel": "self",
          "href": "/mobile/platform/location/devices/11"
        }
      ]
    }
  ],
  "attributes": {
    "hours": "9am-6pm"
  },
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/platform/location/places/11"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/location/places/11"
    }
  ]
}

Accessing the Notifications API from Custom Code

You can use the Notifications API to send a message to the mobile app users, such as an alert about an upcoming event or news that the user might be interested in. You can specify a target for the message such as a device, user, or operating system, and you can schedule the message. You can also inquire about notifications, and delete scheduled notifications that haven’t been sent.

For more information about the ways in which you can use notifications, see Notifications.

This API has the following methods:

Notifications Context Argument

All the Notifications API methods require a context argument, which is a JSON object with the following properties. This information is required to get authorization to send and view the notifications.

Note that the custom code can call mbe.getMBE() to get this information.

Property Desc Type
mbe The name of the mobile backend that’s associated with the notification. String
mbeId (Optional) The ID of the mobile backend that’s associated with the notification. When omitted, the default is the mobile backend id that the mobile application is using. String
version The version of the mobile backend. String
notification.getAll(context, options, httpOptions)

This method lets you retrieve the notifications that match your criteria. Only the notifications that match ALL the criteria are returned.

Arguments

context: Required. JSON object as described in Notifications Context Argument.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
createdOnOrAfter Criteria: Filter by createdOn on or after the given UTC date/time (in YYYY-DD-MM[Thh:mm]Z format). String None
createdOnOrBefore Criteria: Filter by createdOn on or before the given UTC date/time (in YYYY-DD-MM[Thh:mm]Z format). String None
limit The maximum number of items to be returned. If the requested limit is too large, then a lower limit is substituted. Integer None
offset The zero-based index of the first item to return. Integer None
orderBy Specifies the ordering for the query operations. The default sort order is ascending by ID. The format is: "orderBy" "=" 1#( attr [ ":" "asc" | "desc" ] ), where the attr parameter may be id, status, tag, platform, sendOn, createdOn, or processedOn. String None
processedOnOrAfter Criteria: Filter by processedOn on or after the given UTC date/time (in YYYY-DD-MM[Thh:mm]Z format). String None
processedOnOrBefore Criteria: Filter by processedOn on or before the given UTC date/time (in YYYY-DD-MM[Thh:mm]Z format). String None
q Filter results based on a case-insensitive partial match of this string with the tag. For example, q=market returns notifications with tag equal to Marketing, marketing, and markets. String None
sendOnOrAfter Criteria: Filter by sendOn on or after the given UTC date/time (in YYYY-DD-MM[Thh:mm]Z format). String None
sendOnOrBefore Criteria: Filter by sendOn on or before the given UTC date/time (in YYYY-DD-MM[Thh:mm]Z format). String None
status Criteria: Filter by status String None
tag Criteria: Filter by tag String None

Response

The response body is a JSON object that follows the notificationPaging schema that is shown for the GET /mobile/system/notifications/notifications operation in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling this method:

service.get('/mobile/custom/incidentreport/notifications',
  function (req, res) {
    req.oracleMobile.notification.getAll({
      mbe: req.oracleMobile.mbe.getMBE().name,
      version: req.oracleMobile.mbe.getMBE().version})
    .then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of a response body.

{
  "items": [
    {
      "id": 2,
      "message": "Incident Updated: Broken Dryer",
      "users": [
        "J Doe"
      ],
      "roles": [],
      "notificationTokens": [],
      "status": "New",
      "createdOn": "2015-09-24T21:58:04.465Z",
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/system/notifications/notifications/2"
        },
        {
          "rel": "self",
          "href": "/mobile/system/notifications/notifications/2"
        }
      ]
    },
    {
      "id": 3,
      "message": "Incident Updated: Malfunctioning Air Conditioner",
      "users": [
        "Lynn Smith"
      ],
      "roles": [],
      "notificationTokens": [],
      "status": "New",
      "createdOn": "2015-09-24T21:58:07.413Z",
      "links": [
        {
          "rel": "canonical",
          "href": "/mobile/system/notifications/notifications/3"
        },
        {
          "rel": "self",
          "href": "/mobile/system/notifications/notifications/3"
        }
      ]
    }
  ],
  "hasMore": false,
  "limit": 2,
  "count": 2,
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/system/notifications/notifications/?offset=0&limit=2"
    },
    {
      "rel": "self",
      "href": "/mobile/system/notifications/notifications/"
    }
  ]
}
notification.getById(id, context, options, httpOptions)

This method lets you retrieve a specific notification by its ID.

Arguments

id: Required. String or integer. The generated notification ID.

context: Required. JSON object as described in Notifications Context Argument.

options: Optional. JSON object as described in Common options Argument Properties.

Response

The response body is a JSON object that follows the notification schema that is shown for the GET /mobile/system/notifications/notifications/{id} operation in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling the method to get a notification:

service.get('/mobile/custom/incidentreport/notifications/:id',
  function (req, res) {    
    req.oracleMobile.notification.getById(req.params.id, {
        mbe: req.oracleMobile.mbe.getMBE().name,
        version: req.oracleMobile.mbe.getMBE().version})
    .then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of a response body.

{
  "id": 1,
  "message": "Incident Updated: Leaky Faucet",
  "users": [
    "Lynn Smith"
  ],
  "roles": [],
  "notificationTokens": [],
  "status": "New",
  "createdOn": "2015-09-24T21:44:45.708Z",
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/system/notifications/notifications/1"
    },
    {
      "rel": "self",
      "href": "/mobile/system/notifications/notifications/1"
    }
  ]
}
notification.post(notification, context, options, httpOptions)

This method lets you create a notification.

Arguments

notification: Required. JSON object that follows the notificationCreate schema that is shown for the POST /mobile/system/notifications/notifications operation in REST APIs for Oracle Mobile Cloud Service. Here’s an example:

{
    message:'This is the alert message.',
    tag:'Marketing',
    notificationTokens:['APNSdeviceToken']
}

context: Required. JSON object as described in Notifications Context Argument.

options: Optional. JSON object as described in Common options Argument Properties.

Response

The return value includes this header:

Header Description Type
Location Canonical resource URI for the notification. String

The response body, which shows the stored notification, is a JSON object that follows the notification schema that is shown for the POST /mobile/system/notifications/notifications operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example of posting a notification, the request body would look like this: {incidentName: 'Leaky Faucet', customerName: 'Lynn Smith'}.

service.post('/mobile/custom/incidentreport/notifications',
  function (req, res) {
    var notification = {
      sendOn: '2016-06-25T6:00Z',
      message: 'Incident Updated: ' +
      req.body.incidentName,
      users: [req.body.customerName]
    };   
    req.oracleMobile.notification.post(notification, {
        mbe: req.oracleMobile.mbe.getMBE().name,
        version: req.oracleMobile.mbe.getMBE().version})
    .then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Here’s an example of the response body.

{
  "id": 1,
  "message": "Incident Updated: Leaky Faucet",
  "users": [
    "Lynn Smith"
  ],
  "roles": [],
  "notificationTokens": [],
  "sendOn": "2016-06-25T06:00Z",
  "status": "New",
  "createdOn": "2015-06-24T21:44:45.708Z",
  "links": [
    {
      "rel": "canonical",
      "href": "/mobile/system/notifications/notifications/1"
    },
    {
      "rel": "self",
      "href": "/mobile/system/notifications/notifications/1"
    }
  ]
}
notification.remove(id, context, options, httpOptions)

This method lets you delete a notification. You can delete a notification only if its status is Scheduled.

Arguments

id: Required. String or integer. The generated notification ID.

context: Required. JSON object as described in Notifications Context Argument.

options: Optional. JSON object as described in Common options Argument Properties.

Example

Here’s an example of calling this method:

service.delete('/mobile/custom/incidentreport/notifications/:id',
  function (req, res) {
    req.oracleMobile.notification.remove(req.params.id, {
        mbe: req.oracleMobile.mbe.getMBE().name,
        version: req.oracleMobile.mbe.getMBE().version})
    .then(      
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  });

Accessing the Storage API from Custom Code

The Storage API lets you store mobile application objects in the cloud. An object can be text, JSON, or a binary object such as an image. These objects are grouped by collection. To learn about collections and objects, see Storage.

This API has the following methods:

storage.doesCollectionExist(collectionId, options, httpOptions)

You can use this method to determine whether a collection exists. You can also use it to see if the collection matches (or does not match) an ETag.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the collectionId value. This option can be useful for multibyte values. Boolean false
ifMatch The call returns true only if the ETag of the corresponding object matches one of the values specified in this property. String None
ifNoneMatch The call returns true only if the ETag of the corresponding object does not match one of the values specified by this property. String None

Response

This method returns a Boolean value.

Example

The following example uses this method to verify that the collection exists before it stores an object in it.

req.oracleMobile.storage.doesCollectionExist('attachments').then(
  function(result){
    if (result) {
      req.oracleMobile.storage.store('attachments', {id: 'incident412-pic'}, {inType: 'json'}).then(
        function (result) {
          res.status(result.statusCode).send(result.result);
        },
        function (error) {
          res.status(error.statusCode).send(error.error);
        }
      );
    } else {
      res.status(404).send('Storage has not been configured for this app. Please contact your admin.');
    };
  },
  function(error){
    res.status(error.statusCode).send(error.error);
  }
);        
storage.doesExist(collectionId, objectId, options, httpOptions)

You can use this method to determine whether an object exists. You can also use it to see if the object matches (or does not match) an ETag, or if it was modified after a specified date.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

objectId: Required. String. The object being accessed. If the object was stored using the storage.storeById() method, then this is the ID that was provided as the id argument, and, if the object was stored using the storage.store() method, then the ID was generated. When looking at the object metadata, this argument value corresponds to the metadata’s id attribute.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
contentDisposition This property lets you specify the value of the Content-Disposition response header. String None
encodeURI Set to true to URI-encode the collectionId, objectId, and user values. This option can be useful for multibyte values. Boolean false
ifMatch The call completes successfully only if the ETag of the corresponding object matches one of the values specified in this property. String None
ifModifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object was modified after the date specified in this property. You can use this property to reduce the amount of data that is transported by not re-retrieving data if it hasn’t changed. Date None
ifNoneMatch The call completes successfully only if the ETag of the corresponding object does not match one of the values specified by this property. You can use this property to reduce the amount of data that is transported by not re-retrieving data if it hasn’t changed. String None
ifUnmodifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object wasn't modified after the date specified in this property. Date None
user This is the ID (not the user name) of a user. This query parameter allows a user with READ_ALL/READ_WRITE_ALL permission to access another user's isolated space. A user with READ/READ_WRITE permission may access only their own space. String If you are inquiring about a shared collection, there is no default.

If you are inquiring about an isolated collection, and you have READ_ALL/READ_WRITE_ALL permission, then the signed-in user is assumed unless you include this property. If you have READ_ALL/READ_WRITE_ALL permission for an isolated collection, you must include this property to inquire about objects in another user’s space.

Response

This method returns a Boolean value.

Example

In this example, the code calls doesExist to see if the stored object still has the same ETag as when it was last retrieved ("1").

req.oracleMobile.storage.doesExist('attachments', 'incident412-pic', {ifMatch: '\"' + 1 + '\"'}).then(
  function (result) {
    res.status(200).send('Object has not changed.');
  },
  function (error) {
    res.status(412).send('Object was modified by someone else.');
  }
) 
storage.getAll(collectionId, options, httpOptions)

This method returns the metadata for every object in a collection.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the collectionId, orderBy, and user values. This option can be useful for multibyte values. Boolean false
limit The maximum number of items to be returned. If the requested limit is greater than 100, then 100 is used instead. Integer None
offset The zero-based index of the first item to return. Integer None
orderBy Use this property to sort the results by name, modifiedBy, modifiedOn, createdBy, createdOn, or contentLength. You can append :asc or :desc to specify whether to sort in ascending or descending order. For example, modifiedOn:desc. String None
q The items that are returned are based on a case-insensitive partial match of the id, name, createdBy or modifiedBy property of an item. For example, if you set this property to sam, it could return an object with an id of axsam3 and an object with a createdBy of SAMANTHA. String None
sync When this property is present and has a value of true, then the return value contains the information required by the Synchronization library to cache the data locally for offline use. You can get this value from the Oracle-Mobile-Sync-Agent request header, when present. Boolean false
totalResults When this property is present with a value of true, then the response body contains the totalResults attribute with a value that represents the total number of items in the collection. By default, the response does not contain this value. Boolean false
user This is the ID (not the user name) of a user. Use * (wildcard) to get all users. This query parameter allows a user with READ_ALL/READ_WRITE_ALL permission to access another user's isolated space. A user with READ/READ_WRITE permission may access only their own space. String If you are inquiring about a shared collection, there is no default.

If you are inquiring about an isolated collection, and you have READ_ALL/READ_WRITE_ALL permission, then the signed-in user is assumed unless you include this property. If you have READ_ALL/READ_WRITE_ALL permission for an isolated collection, you must include this property to inquire about objects in another user’s space.

Response

The return value includes these headers:

Header Description Type
Cache-Control Describes how the result may be cached. String
Oracle-Mobile-Sync-Resource-Type The Synchronization library uses this header. String

The response body is a JSON object that follows the response body schema that is shown for the GET /mobile/platform/storage/collections/{collection}/objects operation in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling this method. The response lists the objects by modified date, in descending order. Because the sync property is set to true, the client app can cache the response.

// Get metadata about the objects in the attachments collection.
// List most recently modified first.
service.get('/mobile/custom/incidentreport/attachments',
  function (req, res) {
    req.oracleMobile.storage.getAll('attachments', 
    {orderBy: 'modifiedOn:desc', sync: true}).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  }); 

Here’s an example of a response body:

{
    "items":[
        {
            "eTag":"\"2\"",
            "id":"incident412-pic",
            "createdBy":"jdoe",
            "name":"Incident Picture",
            "createdOn":"2014-11-20T19:57:04Z",
            "modifiedOn":"2014-11-20T19:58:09Z",
            "modifiedBy":"jdoe",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/storage/collections/attachments/objects/profile-pic"
                },
                {
                    "rel":"self",
                    "href":"/mobile/platform/storage/collections/attachments/objects/profile-pic"
                }
            ],
            "contentType":"image/png",
            "contentLength":937647
        },
        {
            "eTag":"\"1\"",
            "id":"incident131-pic",
            "createdBy":"jsmith",
            "name":"Incident Picture",
            "createdOn":"2014-11-20T18:27:02Z",
            "modifiedOn":"2014-11-20T18:27:02Z",
            "modifiedBy":"jsmith",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/storage/collections/attachments/objects/0683d48b-fdc5-4397-8ca2-824e2b0cae65"
                },
                {
                    "rel":"self",
                    "href":"/mobile/platform/storage/collections/attachments/objects/0683d48b-fdc5-4397-8ca2-824e2b0cae65"
                }
            ],
            "contentType":"image/jpeg",
            "contentLength":5266432
        }
    ],
    "hasMore":true,
    "limit":2,
    "offset":4,
    "count":2,
    "totalResults":7,
    "links":[
        {
            "rel":"canonical",
            "href":"/mobile/platform/storage/collections/attachments/objects/"
        },
        {
            "rel":"self",
            "href":"/mobile/platform/storage/collections/attachments/objects?offset=4&limit=2&orderBy=name:asc&totalResults=true"
        },
        {
            "rel":"prev",
            "href":"/mobile/platform/storage/collections/attachments/objects?offset=2&limit=2&orderBy=name:asc&totalResults=true"
        },
        {
            "rel":"next",
            "href":"/mobile/platform/storage/collections/attachments/objects?offset=6&limit=2&orderBy=name:asc&totalResults=true"
        }
    ]
}
storage.getById(collectionId, objectId, options, httpOptions)

This method retrieves an object and its metadata from a collection based on the object identifier.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

objectId: Required. String. The object being accessed. If the object was stored using the storage.storeById() method, then this is the ID that was provided as the id argument, and, if the object was stored using the storage.store() method, then the ID was generated. When looking at the object metadata, this argument value corresponds to the metadata’s id attribute.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
contentDisposition This property lets you specify the value of the Content-Disposition response header. String None
encodeURI Set to true to URI-encode the collectionId, objectId, and user values. This option can be useful for multibyte values. Boolean false
ifMatch The call completes successfully only if the ETag of the corresponding object matches one of the values specified in this property. String None
ifModifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object was modified after the date specified in this property. You can use this property to reduce the amount of data that is transported by not re-retrieving data if it hasn’t changed. Date None
ifNoneMatch The call completes successfully only if the ETag of the corresponding object does not match one of the values specified by this property. You can use this property to reduce the amount of data that is transported by not re-retrieving data if it hasn’t changed. String None
ifUnmodifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object wasn't modified after the date specified in this property. Date None
range This property lets you request a subset of bytes. For example, bytes=0–99 gets the first 100 bytes. String None
sync When this property is present and has a value of true, then the return value contains the information required by the Synchronization library to cache the data locally for offline use. You can get this value from the Oracle-Mobile-Sync-Agent request header, when present. Boolean false
user This is the ID (not the user name) of a user. This query parameter allows a user with READ_ALL/READ_WRITE_ALL permission to access another user's isolated space. A user with READ/READ_WRITE permission may access only their own space. String If you are inquiring about a shared collection, there is no default.

If you are inquiring about an isolated collection, and you have READ_ALL/READ_WRITE_ALL permission, then the signed-in user is assumed unless you include this property. If you have READ_ALL/READ_WRITE_ALL permission for an isolated collection, you must include this property to get an object from another user’s space.

Response

The return value includes these headers:

Header Description Type
Accept-Ranges This header indicates that byte ranges may be provided when requesting an object resource. String
Cache-Control Describes how the result may be cached. String
Content-Disposition This response header is returned if the options argument included the contentDisposition property. The value for the response header is the same as the value for the property. String
Content-Length The size of the object in bytes. Number
Content-Type The media type of the object, such as image/jpeg. String
Etag Each item has an ETag value. This value changes each time the item is updated. The value includes the starting and ending quotation marks (for example, "2"). String
Last-Modified The date and time when the resource was last modified. This date is in RFC-1123 format. For example, Fri, 29 Aug 2014 12:34:56 GMT. Date
Oracle-Mobile-Canonical-Link A relative URI that you can use to uniquely reference this object. String
Oracle-Mobile-Created-By The user name of the user who created the object. String
Oracle-Mobile-Created-On The date and time, in ISO 8601 format (for example, 2014-06-30T01:02:03Z), when the object was created. String
Oracle-Mobile-Modified-By The user name of the user who last modified the object. String
Oracle-Mobile-Modified-On The date and time, in ISO 8601 format (for example, 2014-06-30T01:02:03Z), when the object was last modified. String
Oracle-Mobile-Name The display name for the object. String
Oracle-Mobile-Self-Link A relative URI that you can use to uniquely reference this object within the specified isolation level. String
Oracle-Mobile-Sync-Expires This header is used by the Synchronization library. String
Oracle-Mobile-Sync-No-Store This header is used by the Synchronization library. Boolean

The response body is the stored object.

Example

Here is an example of calling this method. Because the sync property is set to true, the client app can cache the response.

req.oracleMobile.storage.getById('attachments', 'incident412-notes', {sync: true}).then(
  function (result) {
    res.status(result.statusCode).send(result.result);
  },
  function (error) {
    res.status(error.statusCode).send(error.error);
  }
); 
storage.getCollection(collectionId, options, httpOptions)

This method returns metadata about a particular collection.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the collectionId value. This option can be useful for multibyte values. Boolean false
ifMatch The call completes successfully only if the ETag of the corresponding object matches one of the values specified in this property. String None
ifNoneMatch The call completes successfully only if the ETag of the corresponding object does not match one of the values specified by this property. String None
sync When this property is present and has a value of true, then the return value contains the information required by the Synchronization library to cache the data locally for offline use. You can get this value from the Oracle-Mobile-Sync-Agent request header, when present. Boolean false

Response

The return value includes these headers:

Header Description Type
Cache-Control Describes how the result may be cached. String
Etag Each item has an ETag value. This value changes each time the item is updated. The value includes the starting and ending quotation marks (for example, "2"). String

The response body is a JSON object that follows the Collection schema that is shown for the GET /mobile/platform/storage/collections/{collection} operation in REST APIs for Oracle Mobile Cloud Service.

Examples

Here’s an example of calling this method. Because the sync property is set to true, the client app can cache the response.

req.oracleMobile.storage.getCollection('attachments', {sync: true}).then(
  function (result) {
    res.status(result.statusCode).send(result.result);
  },
  function (error) {
    res.status(error.statusCode).send(error.error);
  }
); 

Here’s an example of a response body:

{
    "id":"attachments",
    "description":"Attachments for technician notes.",
    "contentLength":6205619,
    "eTag":"\"1.0\"",
    "links":[
        {
            "rel":"canonical",
            "href":"/mobile/platform/storage/collections/attachments"},
        {
            "rel":"self",
            "href":"/mobile/platform/storage/collections/attachments"}
    ]}
storage.getCollections(options, httpOptions)

This method returns metadata about each collection that is available through the mobile backend.

Arguments

options: Optional. JSON Object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
limit The maximum number of items to be returned. If the requested limit is too large, then a lower limit is substituted. Integer None
offset The zero-based index of the first item to return. Integer 0 (zero)
sync When this property is present and has a value of true, then the return value contains the information required by the Synchronization library to cache the data locally for offline use. You can get this value from the Oracle-Mobile-Sync-Agent request header, when present. Boolean false
totalResults When this property is present with a value of true, then the then the response body contains the totalResults property with a value that represents the total number of items in the collection. By default, this property is not returned. Boolean false

Response

The return value includes these headers:

Header Description Type
Cache-Control Describes how the result may be cached. String
Oracle-Mobile-Sync-Resource-Type The Synchronization library uses this header. String

The response body is an array of items in JSON format that follows the Collection Array schema that is shown for the GET /mobile/platform/storage/collections operation in REST APIs for Oracle Mobile Cloud Service.

Example

Here is an example of calling this method. Because the sync property is set to true, the client app can cache the response.

req.oracleMobile.storage.getCollections({sync: true}).then(
  function (result) {
    res.status(result.statusCode).send(result.result);
  },
  function (error) {
    res.status(error.statusCode).send(error.error);
  }
); 

Here’s an example of a response body:

{
    "items":[
        {
            "id":"logs",
            "description":"Application logs.",
            "contentLength":0,
            "eTag":"\"1.0\"",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/storage/collections/logs"},
                {
                    "rel":"self",
                    "href":"/mobile/platform/storage/collections/logs"}
            ]},
        {
            "id":"attachments",
            "description":"Attachments for technician notes.",
            "contentLength":6205619,
            "eTag":"\"1.0\"",
            "links":[
                {
                    "rel":"canonical",
                    "href":"/mobile/platform/storage/collections/attachments"},
                {
                    "rel":"self",
                    "href":"/mobile/platform/storage/collections/attachments"}
            ]}
    ],
    "hasMore":false,
    "limit":100,
    "offset":0,
    "count":2,
    "links":[
        {
            "rel":"canonical",
            "href":"/mobile/platform/storage/collections/"},
        {
            "rel":"self",
            "href":"/mobile/platform/storage/collections?offset=0&limit=100"}
    ]}
storage.remove(collectionId, objectId, options, httpOptions)

This method removes an object from a collection based on the object identifier.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

objectId: Required. String. The ID of the object to remove.

options: Optional. JSON object. This object can have these properties in addition to those listed in Common options Argument Properties:

Property Description Type Default
encodeURI Set to true to URI-encode the collectionId, objectId, and user values. This option can be useful for multibyte values. Boolean false
ifMatch The call completes successfully only if the ETag of the corresponding object matches one of the values specified in this property. You can use this property to ensure that the operation succeeds only if the object wasn't modified after you last requested it. String None
ifModifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object was modified after the date specified in property. Date None
ifNoneMatch The call completes successfully only if the ETag of the corresponding object does not match one of the values specified by this property. String None
ifUnmodifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object wasn't modified after the date specified in this property. You can use this property to ensure that the operation succeeds only if no one modified the object after that time. Date None
user This is the ID (not the user name) of a user. This query parameter allows a user with READ_ALL/READ_WRITE_ALL permission to access another user's isolated space. A user with READ/READ_WRITE permission may access only their own space. String If you are removing an object in a shared collection, there is no default.

If you removing an object in an isolated collection, and you have READ_ALL/READ_WRITE_ALL permission, then the signed-in user is assumed unless you include this property. If you have READ_ALL/READ_WRITE_ALL permission for an isolated collection, you must include this property to remove objects from another user’s space.

Example

This example removes an object from the attachments collection:

service.delete('/mobile/custom/incidentreport/attachments/:id',
  function (req, res) {
    req.oracleMobile.storage.remove('attachments', req.params.id).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    );
  }); 
storage.store(collectionId, object, options, httpOptions)

This method lets you store an object and have an identifier automatically assigned to it.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

object: Required. Text, JSON object, file, or binary object. The object to store.

options: Optional. JSON object. This object can have the following properties in addition to those listed in Common options Argument Properties. Note that the contentType property plays an important role for Storage, because that also specifies the mediat type to when the object is requested. If you don't include the content, then the content-type defaults to application/octet-stream.

Property Description Type Default
contentLength The size of the object in bytes. Number If the object is a string or a buffer, then the default is object.length. Otherwise, the default is the sum of its members’ lengths.
contentType The media type of object being stored. This property also specifies the media type to return when the object is requested. String If the inType is json, then the Content-Type header is set to application/json automatically. Otherwise, the default isapplication/octet-stream.
encodeURI Set to true to URI-encode the collectionId, mobileName, and user values. This option can be useful for multibyte values. Boolean false
mobileName The display name for the object. If you don't include the display name, the name is set to the object identifier that this method generates automatically. String None
user This is the ID (not the user name) of a user. This query parameter allows a user with READ_ALL/READ_WRITE_ALL permission to access another user's isolated space. A user with READ/READ_WRITE permission may access only their own space. String If you are storing an object in a shared collection, there is no default.

If you storing an object in an isolated collection, and you have READ_ALL/READ_WRITE_ALL permission, then the signed-in user is assumed unless you include this property. If you have READ_ALL/READ_WRITE_ALL permission for an isolated collection, you must include this property to store objects in another user’s space.

Response

The return value includes this header:

Header Description Type
Location The URI that corresponds to the newly created object. String

The response body is a JSON object that follows the schema shown for the response body for the POST /mobile/platform/storage/collections/{collection}/objects operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, requests can contain JSON objects, files, plain text, images, and so forth. If the input is a JSON object then it must set inType to json, and pass in req.body for the object. Otherwise, it sets inType to stream, and passes in req for the object.

service.post('/mobile/custom/incidentreport/attachments',
function (req, res) {
  if (req.is('json')) {
    // Must specify JSON because there is no stream to pipe from req
    // as Express has read it into json and put it in req.body.
    req.oracleMobile.storage.store('attachments', req.body,
      {
        mobileName: 'Technician Notes',
        inType: 'json',
        outType: 'stream'
      })
      .on('error', function (error) {
        res.status(error.statusCode).send(error.message)
      })
      .pipe(res);
  } else {
    // For streaming, send req instead of req.body
    req.oracleMobile.storage.store('attachments', req, {
      mobileName: 'Technician Notes',
      contentType: req.header('content-type'),
      inType: 'stream',
      outType: 'stream'
    })
      .on('error', function (error) {
        res.status(error.statusCode).send(error.message)
      })
      .pipe(res);
  }
});  

In this example, the request body contains a Base-64 encoded image. The code converts it to a binary image before storing it. The request body would look like this:

{
  imageName: 'brokenWaterHose', 
  base74EncodedImage: '/9j/4AAQSkZJRg...AFFFFAH/2Q=='
}
// Base 64 
service.post('/mobile/custom/incidentreport/attachments',
  function (req, res) {
    // convert Base-64 encoded image to binary image
    image = new Buffer(req.body.base64EncodedImage);
    req.oracleMobile.storage.store('attachments', image,
      {
        contentType: 'image/jpeg',
        mobileName: req.body.imageName
      }
    ).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      }
    )
  })

Here’s an example of a response body:

{
    "eTag":"\"1\"",
    "id":"a95edb6f-539d-4bac-9ffa-78ff16b20516",
    "createdBy":"jdoe",
    "name":"Technician Notes",
    "createdOn":"2014-11-20T15:53:05Z",
    "modifiedOn":"2014-11-20T15:53:05Z",
    "modifiedBy":"jdoe",
    "links":[
        {
            "rel":"canonical",
            "href":"/mobile/platform/storage/collections/attachments/objects/a95edb6f-539d-4bac-9ffa-78ff16b20516"
        },
        {
            "rel":"self",
            "href":"/mobile/platform/storage/collections/attachments/objects/a95edb6f-539d-4bac-9ffa-78ff16b20516"
        }
    ],
    "contentType":"application/json",
    "contentLength":9377
}
storage.storeById(collectionId, objectId, object, options, httpOptions)

This method stores an object based on an ID that you specify. You can use it to add an object using your own ID instead of one that is generated automatically, or to update an existing object.

Arguments

collectionId: Required. String. The name of the collection. When you look at the metadata for the collection, this value corresponds to the metadata’s id value.

objectId: Required. String. If you are adding an object, this is the ID to store the object under. If you are updating an object, this is the ID of the object you are replacing.

object: Required. Text, JSON object, file, or binary object. This is the object to store.

options: Optional. JSON object. This object can have the following properties in addition to those listed in Common options Argument Properties.

Property Description Type Default
contentLength The size of the object in bytes. Number If the object is a string or a buffer, then the default is object.length. Otherwise, the default is the sum of its members’ lengths.
contentType The media type of object being stored. This property also specifies the media type to return when the object is requested. String If the inType is json, then the Content-Type header is set to application/json automatically. Otherwise, the default isapplication/octet-stream.
encodeURI Set to true to URI-encode the collectionId, objectId, mobileName, and user values. This option can be useful for multibyte values. Boolean false
ifMatch The call completes successfully only if the ETag of the corresponding object matches one of the values specified in this property. You can use this property to ensure that the operation succeeds only if the object wasn't modified after you last requested it. String None
ifModifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object was modified after the date specified in property. Date None
ifNoneMatch The call completes successfully only if the ETag of the corresponding object does not match one of the values specified by this property. String None
ifUnmodifiedSince Date and time in HTTP-date format. For example, Mon, 30 Jun 2014 19:43:31 GMT. The request completes successfully only if the object wasn't modified after the date specified in this property. You can use this property to ensure that the operation succeeds only if no one modified the object after that time. Date None
mobileName The display name for the object. If you don't include the display name, the name is set to the object identifier. String None
user This is the ID (not the user name) of a user. This query parameter allows a user with READ_ALL/READ_WRITE_ALL permission to access another user's isolated space. A user with READ/READ_WRITE permission may access only their own space. String If you are storing an object in a shared collection, there is no default.

If you storing an object in an isolated collection, and you have READ_ALL/READ_WRITE_ALL permission, then the signed-in user is assumed unless you include this property. If you have READ_ALL/READ_WRITE_ALL permission for an isolated collection, you must include this property to store objects in another user’s space.

Response

The response body is a JSON object that follows the schema shown for the response body for the PUT /mobile/platform/storage/collections/{collection}/objects/{object} operation in REST APIs for Oracle Mobile Cloud Service.

Examples

In this example, the request can contain JSON objects, files, plain text, images, and so forth. If the input is a JSON object then it must set inType to json, and pass in req.body for the object. Otherwise, it sets inType to stream, and passes in req for the object.

service.put('/mobile/custom/incidentreport/attachments/:id',
function (req, res) {
  if (req.is('json')) {
    // Must specify JSON because there is no stream to pipe from req
    // as Express has read it into json and put it in req.body.
    req.oracleMobile.storage.storeById('attachments', req.params.id, req.body,
      {
        contentLength: req.body.length,
        mobileName: 'Technician Notes',
        inType: 'json',
        outType: 'stream'
      })
      .on('error', function (error) {
        res.status(error.statusCode).send(error.message)
      })
      .pipe(res);
  } else {
    // For streaming, send req instead of req.body
    req.oracleMobile.storage.storeById('attachments', req.params.id, req, {
      mobileName: 'Technician Notes',
      contentType: req.header('content-type'),
      inType: 'stream',
      outType: 'stream'
    })
      .on('error', function (error) {
        res.status(error.statusCode).send(error.message)
      })
      .pipe(res);
  }
});  

Here’s an example of a response body:

{
    "eTag":"\"2\"",
    "id":"incident412-notes",
    "createdBy":"jdoe",
    "name":"Technician Notes",
    "createdOn":"2014-11-20T15:57:04Z",
    "modifiedOn":"2014-11-20T15:58:09Z",
    "modifiedBy":"jdoe",
    "links":[
        {
            "rel":"canonical",
            "href":"/mobile/platform/storage/collections/attachments/incident412-notes"},
        {
            "rel":"self",
            "href":"/mobile/platform/storage/collections/attachments/incident412-notes"}
    ],
    "contentType":"application/json",
    "contentLength":9377
}

Accessing the Mobile Users API from Custom Code

The Mobile Users and Mobile Users Extended Operations APIs let you get information about the current mobile, virtual, or social user. In addition, the Mobile Users API lets you update a mobile user’s custom properties. Custom properties are properties that a mobile cloud administrator has added to the user’s realm.

This API has the following methods:

ums.getUser(options, httpOptions)

This method lets you retrieve the information about the current user.

  • When the user is a mobile user, this operation retrieves the user name, first name, last name, and email address as well as the custom properties that were added to the realm that the user belongs to.

  • When the user is a virtual user, this operation retrieves the user name. To learn about virtual users, see Configuring SAML Tokens for Virtual Users.

  • When the user is a social user (that is, signed in using social identity), this operation retrieves the user's ID, identity provider, and access token. To learn about social users and social identity, see Facebook Login in MCS.

Arguments

options: Optional. JSON object. For mobile users, this object can have the following property in addition to those listed in Common options Argument Properties:

Property Description Type Default
fields Specifies which user properties to get. For example, you can set options.fields to firstName,lastName to retrieve just those two values. This property is ignored if the current user signed in using virtual or social identity. String None

Response

If the current user is a social user, then the response body includes the generated username as well as the mobileExtended.identityProvider properties, as shown in this example. To learn more about social identity see Facebook Login in MCS.

    "username": "1 :623:165",
    "mobileExtended": {
        "identityProvider": {
            "facebook": {
                "accessToken":"CAAI...YZD"
            }
        }
    }

If the current user is a virtual user, then the response body includes the username, as shown in this example.

    "username": "a24x"

In all other cases, the response body is a JSON object that contains one or more of the following properties, depending on the value of the request’s options.fields property.

  • id

  • email

  • firstName

  • lastName

  • username

  • Custom properties that have been added to the realm that the user belongs to.

Examples

Here’s an example of calling this method to get the user’s first and last name. In this example, the user is a mobile user:

req.oracleMobile.ums.getUser({fields: 'firstName,lastName'}).then(
  function(result){
    res.send(result.statusCode, result.result);
  },
  function(error){
    res.send(error.statusCode, error.error);
  }
);

This example shows the response that you get when you set the options.fields property to firstname,lastname:

{
  "firstName": "Joe",
  "lastName": "Doe"
}

Here’s an example of calling this method to get all the fields for a mobile user:

req.oracleMobile.ums.getUser().then(
  function(result){
    res.send(result.statusCode, result.result);
  },
  function(error){
    res.send(error.statusCode, error.error);
  }
);

Here’s an example of a response body for this request:

{
  "id":"295e450a-63f0-41fa-be43-cd2dbcb21598",
  "username":"joe",
  "email":"joe@example.com",
  "firstName":"Joe",
  "lastName":"Doe",
  "links":[
    {
      "rel":"canonical",
      "href":"/mobile/platform/users/joe"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/users/joe"
    }    
  ]
}
ums.getUserExtended(options, httpOptions)

This method lets you retrieve the information about the authorized user, including the user's roles.

  • When the user is a mobile user, this operation retrieves the user name, first name, last name, roles, and email address as well as the custom properties that were added to the realm that the user belongs to.

  • When the user is a virtual user, this operation retrieves the user name and roles. To learn about virtual users, see Configuring SAML Tokens for Virtual Users.

  • When the user is a social user (that is, signed in using social identity), this operation retrieves the user's ID, identity provider, and access token. To learn about social users and social identity, see Facebook Login in MCS.

Arguments

options: Optional. JSON object. For mobile users, this object can have the following property in addition to those listed in Common options Argument Properties:

Property Description Type Default
fields Specifies which user properties to get. For example, you can set options.fields to firstName,lastName to retrieve just those two values. This property is ignored if the current user signed in using virtual or social identity. String None

Response

If the current user is a social user, then the response body includes the generated username as well as the mobileExtended.identityProvider properties, as shown in this example.

    "username": "1 :623:165",
    "mobileExtended": {
        "identityProvider": {
            "facebook": {
                "accessToken":"CAAI...YZD"
            }
        }
    }

If the current user is a virtual user, then the response body includes the username and roles properties, as shown in this example.

    "username": "a24x",
    "roles": [
      "Customer", "Trial"
    ]

In all other cases, the response body is a JSON object that contains one or more of the following properties, depending on the value of the request’s options.fields property.

  • id

  • email

  • firstName

  • lastName

  • username

  • roles (array)

  • Custom properties that have been added to the realm that the user belongs to.

The response body also contains links to the API endpoint for the resource.

Examples

Here’s an example of calling this method to get a mobile user’s first and last name:

req.oracleMobile.ums.getUserExtended({fields: 'firstName,lastName'}).then(
  function(result){
    res.send(result.statusCode, result.result);
  },
  function(error){
    res.send(error.statusCode, error.error);
  }
);

This example shows the response that you get when you set the options.fields property to firstname,lastname:

{
  "firstName": "Joe",
  "lastName": "Doe"
}

Here’s an example of calling this method to get all the fields for a mobile user.

req.oracleMobile.ums.getUserExtended().then(
  function(result){
    res.send(result.statusCode, result.result);
  },
  function(error){
    res.send(error.statusCode, error.error);
  }
);

Here’s an example of a response body for this request:

{
  "id":"295e450a-63f0-41fa-be43-cd2dbcb21598",
  "username":"joe",
  "email":"joe@example.com",
  "firstName":"Joe",
  "lastName":"Doe",
  "roles": [
    "Customer", "Trial"
  ],
  "links":[
    {
      "rel":"canonical",
      "href":"/mobile/platform/users/joe"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/users/joe"
    }    
  ]
}
ums.updateUser(fields, options, httpOptions)

This method lets you update the custom properties that were added to the realm that the mobile backend is associated with. Note that you can’t use this API to update the built-in properties, such as username.

Arguments

fields: Required. A JSON object that contains name/value for custom fields to be updated. For example:{birthdate: '07/21/71', language: 'en'}. Only primitive data types are supported.

options: Optional. A JSON object as described in Common options Argument Properties.

Response

The response body is a JSON object where the name/value pairs represent the user properties. It also contains links to the API endpoint for the resource.

Examples

Here’s an example of calling this method to update the custom property key. In this example, the request body would look like this: {key: 'Ax47Y'}.
service.put(
  '/mobile/custom/incidentreport/key',
  function (req, res) {
    req.oracleMobile.ums.updateUser({key: req.body.key}).then(
      function (result) {
        res.send(result.statusCode, result.result);
      },
      function (error) {
        res.send(error.statusCode, error.error);
      }
    );
  });
Here’s an example of a response body:
{
  "id":"295e450a-63f0-41fa-be43-cd2dbcb21598",
  "username":"joe",
  "email":"joe@example.com",
  "firstName":"Joe",
  "lastName":"Doe",
  "key":"Ax47Y",
  "links":[
    {
      "rel":"canonical",
      "href":"/mobile/platform/users/joe"
    },
    {
      "rel": "self",
      "href": "/mobile/platform/users/joe"
    }    
  ]
}

Calling Custom APIs from Custom Code

The custom code SDK provides two namespaces for sending requests to other custom APIs:

  • oracleMobile.custom.<apiName>: To use the methods in this namespace, you must explicitly declare in package.json a dependency on the custom API.

  • oracleMobile.custom: To use the methods in this namespace, you don’t need to explicitly declare in package.json a dependency on the custom API.

There are several reasons for declaring the dependency in package.json, such as making it easier to track dependencies, and ensuring that dependent APIs are published when you publish your API. To learn how to declare a dependency in package.json and the advantages for doing so, see Specifying the API Version in Calls to Custom and Connector APIs.

The optional options argument can have this property in addition to those listed in Common options Argument Properties.

Property Description Type Default
versionToInvoke The version of the custom API.

When you use the oracleMobile.custom namespace, you must include this option if the API version is not declared in package.json.

When you use the oracleMobile.custom.<apiName> namespace, the API version must be declared in package.json, and you optionally can use this property to override that version.

String The version that is declared in the package.json file.

Both namespaces provide methods for each HTTP operation, as shown in this table:

HTTP Operation oracleMobile.custom Method oracleMobile.custom.<apiName> Method
GET get(apiName, resourceName, options, httpOptions) get(resourceName, options, httpOptions)
PUT put(apiName, resourceName, object, options, httpOptions) put(resourceName, object, options, httpOptions)
POST post(apiName, resourceName, object, options, httpOptions) post(resourceName, object, options, httpOptions)
DELETE del(apiName, resourceName, options, httpOptions) del(resourceName, options, httpOptions)
HEAD head(apiName, resourceName, options, httpOptions) head(resourceName, options, httpOptions)
OPTIONS options(apiName, resourceName, options, httpOptions) options(resourceName, options, httpOptions)
PATCH patch(apiName, resourceName, object, options, httpOptions) patch(resourceName, object, options, httpOptions)

Here are examples of how to call another custom API from custom code using both namespaces . These examples call the motd custom API, and send a POST request to its years/{year}/months/{month}/days resource.

  /**
   *  oracle.Mobile.custom.<apiName> namespace example:
   *
   *  <namespace>.post(<resource>, <body>, <options>)
   *
   *  Note: Because it uses the 
   *  oracleMobile.custom.<apiName> namespace,
   *  the dependency on the motd API must
   *  be specified in package.json.
   *  options.versionToInvoke isn't required. You can use
   *  it to override the version that is declared in 
   *  package.json.
   */      
  req.oracleMobile.custom.motd.post(
    'years/2018/months/1/days', 
    req.body, 
    {inType: 'json'}).then(
    function (result) {
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      res.status(error.statusCode).send(error.error);
    }
  );       
  /**
   *  oracle.Mobile.custom namespace example:
   *
   *  post(<namespace>, <resource>, <body>, <options>)
   *
   *  You must include the versionToInvoke option if
   *  the API isn't declared in package.json.
   */      
  req.oracleMobile.custom.post(
    'motd',
    'years/2018/months/1/days', 
    req.body, 
    {versionToInvoke: '1.0', inType: 'json'}).then(
    function (result) {
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      res.status(error.statusCode).send(error.error);
    }
  ); 

Calling Connector APIs from Custom Code

To use a connector, you must create a custom API and implement code that calls the SDK’s connector methods. Here’s information about how to call a connector from custom code.

Tip:

If your connector is a REST API that you created using a valid descriptor, then you can create the custom API and its implementation automatically, as described in How Do I Generate a Custom API from a Connector. If you use the automatic-generation feature, you typically don’t need to know how to use the SDK’s connector methods described here unless you are using the customizer method that is in the generated code. For example, you might need to use a customizer to pass options.externalAuthorization . Sometimes, you might need to replace a call to the callConnector method with your own code, such as when you need to send multipart form data or the http options object.

The custom code SDK provides two namespaces for sending requests to connectors:

  • oracleMobile.connectors.<connector>: To use the methods in this namespace, you must explicitly declare in package.json a dependency on the connector. The automatically generated implementations use this namespace.

  • oracleMobile.connectors: To use the methods in this namespace, you don’t need to explicitly declare in package.json a dependency on the connector.

There are several reasons for declaring the dependency in package.json, such as making it easier to track dependencies, and ensuring that dependent APIs are published when you publish your API. To learn how to declare a dependency in package.json and the advantages for doing so, see Specifying the API Version in Calls to Custom and Connector APIs.

The optional options argument can have these properties in addition to those listed in Common options Argument Properties.

Property Description Type Default
externalAuthorization If you haven’t configured a security policy for the connector, then put the Authorization value for the external service in the options.externalAuthorization property. When this property is present, the connector sets the outgoing Authorization header with the value in options.externalAuthorization property before it sends the request to the external service. String None
versionToInvoke The version of the connector.

When you use the oracleMobile.connectors namespace, you must include this option if the API version is not declared in package.json.

When you use the oracleMobile.connectors.<connector> namespace, the API version must be declared in package.json, and you optionally can use this property to override that version.

String The version that is declared in the package.json file. When you use the oracleMobile.connectors.<connector> namespace, the API version must be declared in package.json.

Both namespaces provide methods for each HTTP operation, as shown in this table:

HTTP Method oracleMobile.connectors Signature oracleMobile.connectors.<connector> Signature
GET get(connector, resourceName, options, httpOptions) get(resourceName, options, httpOptions)
PUT put(connector, resourceName, object, options, httpOptions) put(resourceName, object, options, httpOptions)
POST post(connector, resourceName, object, options, httpOptions) post(resourceName, object, options, httpOptions)
DELETE del(connector, resourceName, options, httpOptions) del(resourceName, options, httpOptions)
HEAD head(connector, resourceName, options, httpOptions) head(resourceName, options, httpOptions)
OPTIONS options(connector, resourceName, options, httpOptions) options(resourceName, options, httpOptions)
PATCH patch(connector, resourceName, object, options, httpOptions) patch(resourceName, object, options, httpOptions)

Note:

You use the Network_HttpPatch environment policy to control the behavior of PATCH requests.
  • HEADER sends a POST request with an X-HTTP-Method-Override header set to PATCH. This enables you to send PATCH requests when the target server doesn’t support the PATCH method.

  • LEGACY sends a PATCH request with an X-HTTP-Method-Override header set to PATCH. This is consistent with the behavior of environments that were provisioned before 18.2.3.

  • METHOD sends a PATCH request without an X-HTTP-Method-Override header set to PATCH.

For environments that were provisioned before 18.2.3, the default is LEGACY. For environments that were provisioned on or after 18.2.3, the default is METHOD. Here’s an example of using a policy setting to change the policy for MyRESTConnector:

*.connector/MyRESTConnector(1.0).Network_HttpPatch=HEADER

To learn about viewing and changing environment policies, see Modifying an Environment Policy.

Here’s an example of calling the /mobile/connector/globalweather connector using the oracleMobile.connectors namespace:

req.oracleMobile.connectors.post('globalweather', 'GetWeather', body,
{inType: 'json', versionToInvoke: '1.0'}).then(
  function (result) {
    console.info("result is: " + result.statusCode);
    res.status(result.statusCode).send(result.result);
  },
  function (error) {
    console.info("error is: " + error.statusCode);        
    res.status(error.statusCode).send(error.error);
  }
);

Here’s an example of calling the /mobile/connector/globalweather connector using the oracleMobile.connectors.<connector> namespace.

req.oracleMobile.connectors.globalweather.post('GetWeather', body, {inType: 'json'}).then(
  function (result) {
    res.status(result.statusCode).send(result.result);
  },
  function (error) {      
    res.status(error.statusCode).send(error.error);
  }
);

Calling a Connector to a REST Web Service

You need the connector name and the resource name to call a REST API connector. You form the resource name by removing the base URI from the endpoint. Say, for example, that your git connector maps to https://example.com. To call https://example.com/{owner}/{repo}/contents/{path}, set the resourceName to {owner}/{repo}/contents/{path}.

You also need to pass the authorization in either options.externalAuthorization or httpOptions.headers['oracle-mobile-external-authorization'] .

Here’s an example of sending a PUT request to a REST connector:

service.put('/mobile/custom/incidentreport/connectors/git/:owner/:repo/contents/:path',
  function (req, res) {
    req.oracleMobile.connectors.idmsamples.put(
      'repos/' + req.params.owner + '/' + req.params.repo + '/contents/' + req.params.path, 
      req.body, 
      {externalAuthorization: req.header('external-authorization'), inType: 'json'}, 
      null).then(
        function (result) {
          // include the target service's response headers
          res.set(result.headers);
          res.status(result.statusCode).send(result.result);
        },
        function (error) {
          res.status(error.statusCode).send(error.error);
        }
    );
});

You use the httpOptions object to pass headers and query parameters to a connector.

Note:

A connector to a REST web service can have rules that set default query parameters. If you specify values for those same parameters, then your values take precedence and override the default parameters in the connector rules.

Here’s an example of passing query parameters and headers in the httpOptions object:

service.get('/mobile/custom/incidentreport/connectors/git/:owner/:repo/contents/:path',
  function (req, res) {
    req.oracleMobile.connectors.idmsamples.get(
      'repos/' + req.params.owner + '/' + req.params.repo + '/contents/' + req.params.path,
      {externalAuthorization: req.header('external-authorization')}, 
      {qs: {"branch": req.query.branch}, headers: {"accept": req.header('accept')}}
       ).then(
        function (result) {
          res.status(result.statusCode).send(result.result);
        },
        function (error) {
          res.status(error.statusCode).send(error.error);
        }
      );    
});

Tip:

When you use httpOptions.qs to pass the query string, you can use encodeURIComponent(<string>) for the qs value to ensure that your code handles multibyte characters.

To learn how to create a connector to a REST service, see REST Connector APIs.

Calling a Connector to a SOAP Service

The body for a message that you send to a SOAP connector must be in either the XML or JSON form of a SOAP envelope, with an optional Header, a required Body, and an optional Fault.

JSON requests are translated automatically to XML, and XML responses are translated to JSON. This means that you can interact with SOAP services without having to work with XML. See How Does XML Get Translated into JSON? for conditions that you should be aware of when the translation occurs.

If you choose to provide the message in XML, then remember to do the following:

  • To request that the response body is in XML format, set options.accept to application/xml.

  • When the request body is in XML format, set options.contentType to application/xml; charset=utf-8.

  • The XML in a request body must be wrapped in a SOAP envelope, which must include any necessary SOAP headers, as shown in this example. If you configured a security policy on a connector that requires a SOAP header to be sent in the message, That header is added automatically so you don’t need to include it in your message.

    <?xml version="1.0" ?>
    <SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemad.xmlsoap.org/soap/envelope">
    
      <SOAP-ENV:Header>
        <!-- Add any SOAP headers here -->
      </SOAP-ENV>
    
      <SOAP-ENV:Body>
        <!-- Add the Body element here -->
      </SOAP-ENV:Body>
    
    </SOAP-ENV:Envelope>

To see a sample message for a connector’s operation, go to the Test page for the connector, select the operation, and then click Examples.

Note that with SOAP connectors, if your options.contentType property doesn’t specify the character set, then UTF-8 is assumed.

Here’s an example of calling a connector to a SOAP service. In this example, the request body is in JSON format:

service.get('/mobile/custom/incidentreport/connectors/numberConvert/:number/words',
function (req, res) {
  var body = {
    Header: null,
    Body: {
       "NumberToWords": {
          "ubiNum": req.params.number
      }
    }
  };
  req.oracleMobile.connectors.post('numberConvert', 'words', body,
  {inType: 'json', versionToInvoke: '1.0'}).then(
    function (result) {
      res.status(result.statusCode).send(result.result);
    },
    function (error) {      
      res.status(error.statusCode).send(error.error);
    }
  );
});

To learn how to create a connector to a SOAP service, see SOAP Connector APIs.

Calling Connectors that Require Form Data

If a connector’s operation requires a content type of multipart/form-data, use Multer to pass the form data to the connector. Multer is a library for Node.js that handles multipart form data.

To call a connector with a request body of type multipart/form-data:

  1. Add multer as a dependency in package.json, as shown in the following example, and then run npm install.

    {
      "name": "sendformdata",
      "version": "1.0.0",
      "description": "Sends form data to a connector API.",
      "main": "sendformdata.js",
      "dependencies": {
        "multer": "latest"
      },
      ...
    }
  2. In the custom code, add the following statements:

    var multer = require('multer');
    var storage = multer.memoryStorage();
    var upload = multer({storage: storage});
    

    Multer adds the following objects to the incoming request body when it is of type multipart/form-data:

    • body: Contains the text fields that are in the form.

    • files: Contains the files that are uploaded using the form.

  3. In the method for the operation, pass upload.array as the second argument and provide the name of the form’s file parameter and the maximum number of uploaded files. For example:

    service.post('/mobile/custom/SendFormData/upload', upload.array("avatar", 12), function (req, res)
  4. Extract the content from the body and files objects and pass it to the connector via the httpOptions.formData object. Note that you must make the file object look like a stream.

Here’s an example. In this example, the POST /mobile/custom/SendFormData/upload operation requires the following form parameters:

  • username, which is of type text.

  • avatar, which is of type file.

var multer = require('multer');
var storage = multer.memoryStorage();
var upload = multer({storage: storage});

module.exports = function (service) {

   service.post('/mobile/custom/SendFormData/upload', upload.array("avatar", 12), function (req, res) {

    // Because the uploaded file is a buffer in memory, you must modify it
    // to look like a stream before you send it to the connector.
    var uploadedFile = {
      value: req.files[0].buffer,
      options: {
        filename: req.files[0].originalname,
        contentType: req.files[0].mimetype
      }
    };
    
    var formData = {
      username: req.body.username,
      avatar: uploadedFile
    };

    // FormData is the name of the connector.
    // The formData object is passed in the httpOptions argument.
    // The options.contentType is set to multipart/form-data automatically.
    req.oracleMobile.connectors.FormData.post("upload", null, null, {
      formData: formData
    }).then(
      function (result) {
        res.status(result.statusCode).send(result.result);
      },
      function (error) {
        res.status(error.statusCode).send(error.error);
      });
  });
};

For information about Multer, see https://www.npmjs.com/package/multer.

Passing Headers to the Target Service

With the exception of the following headers, you must use httpOptions.headers to pass headers and their values:

  • Authorization: If the connector doesn’t have a connector Authorization header rule, or if you don’t want to use the rule’s default value, then you must pass the authorization information in either the options.externalAuthorization property or the httpOptions.headers['oracle-mobile-external-authorization'] property, as shown here. See Security and REST Connector APIs.

  • Connection: Don’t set this header.

  • Content-Length: Don’t set this header.

  • Host: Don’t set this header.

  • User-Agent: Don’t set this header.

Note:

The original request’s Accept value isn’t passed to the target service. To pass the value to the target service, use either the httpOptions.headers.accept property or the options.accept property.

The headers that you pass in your request override any related default values that are set by connector rules.

Here’s an example that passes headers to the target service:

  var httpOptions={'headers':{}};
  // You must pass the Accept header if you don't want to use the target server's default.
  if (req.header('accept')) {
    // You can pass the accept value using options.accept or httpOptions.header, as shown here:
    httpOptions.headers.accept = req.header('accept');
  };
  // If the connector doesn't have an Authorization rule, 
  // or if you don't want to use the rule's default,
  // pass the authorization information using options.externalAuthorization or
  // httpOptions.headers.oracle-mobile-external-authorization.
  // Note the ['']syntax to prevent the hyphen from being interpreted as a minus.
  if (req.header('external-authorization')) {
      httpOptions.headers['oracle-mobile-external-authorization'] = 
        req.header('external-authorization');
  };
  // Pass any custom headers    
  if (req.header('if-none-match')) {
     httpOptions.headers['if-none-match'] = req.header('if-none-match');
  }; 
  req.oracleMobile.connectors.git.get('repos/fixItFast/incidentreport/contents/README.md', 
    null,
    httpOptions).then(
    function (result) {
      // include the target service's headers
      res.set(result.headers);
      res.status(result.statusCode).send(result.result);
    },
    function (error) {
      res.status(error.statusCode).send(error.error);
    }
  );

Overriding SSL Settings for Connectors

You might encounter issues with external services, such as the service has an invalid SSL certificate or it redirects the request but it doesn't preserve the cookies over the redirect.

To resolve these issues, you use the options argument to customize the outgoing HTTP requests, which go through a proxy. You can get the proxy from req.oracleMobile.proxy.httpProxy. Here’s an example of how to override the strictSSL setting in order to ignore SSL validation issues.

var res = {};
var options = { 
  uri: req.body.externalURI, 
  strictSSL: false, 
  proxy: 'http://' + req.oracleMobile.proxy.httpProxy
} 
req(options).pipe(res);

To learn more about request options, see https://github.com/request/request#requestoptions-callback.

Specifying the API Version in Calls to Custom and Connector APIs

When you call connector APIs or other custom APIs, you must always specify the API version. You can specify the API version in one of the following ways:

  • Explicitly state the version dependency in the implementation’s package.json file, as shown here. You must do this if you are using methods in the oracleMobile.connectors.<connector> or oracleMobile.custom.<apiName> namespace.

    {
      "name" : "incidentreports",
      "version" : "1.0.0",
      "description" : "FixItFast Incident Reports API",
      "main" : "incidentreports.js",
      "oracleMobile" : {
        "dependencies" : {
          "apis" : {"/mobile/custom/motd" : "1.0"},
          "connectors" : {"/mobile/connector/geocoder": "1.0"}
        }
      }
    }

    In this example, a call to any method in the oracleMobile.custom.motd namespace uses version 1.0 by default.

    For more information, see package.json Contents.

  • Include the options.versionToInvoke property in the request and set it to the version that you want to use (represented as a string). If you specify the version number this way, then it overrides what you may have specified in the package.json file.

    req.oracleMobile.custom.post(
        'motd',
        'years/2018/months/1/days', 
        req.body, 
        {versionToInvoke: '1.0', inType: 'json'}).then(
        function (result) {
          res.status(result.statusCode).send(result.result);
        },
        function (error) {
          res.status(error.statusCode).send(error.error);
        }
      );
    

    Note:

    If you are using a method from the generic oracleMobile.rest namespace, then put the version in the Oracle-Mobile-API-Version header instead of the options.versionToInvoke property.

When you declare dependencies using the package.json file, then it’s easier to keep track of those dependencies than when you use the options.versionToInvoke property to declare dependencies. When you use package.json for this purpose, the API Designer displays the dependencies in a table below the list of implementations. When you prepare to publish your API, you’re prompted to publish any unpublished dependent APIs.

However, if you use the options.versionToInvoke property to declare the version of a dependent API, the API Designer won’t be aware of that dependency and won’t prompt you with information when you publish the calling API. In this case, you’ll need to remember to publish the dependent API yourself.

Using Generic REST Methods to Access APIs

Earlier versions of the custom code SDK used oracleMobile.rest methods to access custom, platform, and connector APIs. To ensure backwards compatibility, these methods continue to be available.

The legacy methods take two options: optionsList, which you use to pass request details, and handler, which is an optional function to be executed by the method. If you don’t include the handler argument, then the method returns a promise. A promise represents the result of an asynchronous request. At the time it is issued, the request may or may not have completed. You typically use a promise with the then function.

If the handler function makes calls to other custom, platform, or connector APIs, then you must follow Request.js conventions as described at https://github.com/request/request.

This API has legacy and asynchronous methods for each HTTP operation, as shown in the next table. The difference between the legacy and asynchronous methods is that asynchronous methods don’t have a handler argument. They always return a promise.
HTTP Operation oracleMobile.rest Methods
GET get(optionsList, handler)

getAsync(optionsList)

PUT put(optionsList, handler)

putAsync(optionsList)

POST post(optionsList, handler)

postAsync(optionsList)

DELETE del(optionsList, handler)

delAsync(optionsList)

HEAD head(optionsList, handler)

headAsync(optionsList)

OPTIONS options(optionsList, handler)

optionsAsync(optionsList)

PATCH patch(optionsList, handler)

patchAsync(optionsList)

Here’s an example of using an oracleMobile.rest method to access the Database Service API. Notice how it uses optionsList to pass in the URI and query string, and to convert the request body to JSON.

// The request body looks like this
// {title:'Water heater is leaking', technician:'jwhite',customer:'Lynn Smith'}
service.post('/mobile/custom/incidentreport/incidents',
function (req, res) {

  var optionsList = {
    uri: '/mobile/platform/database/objects/FIF_Incidents',
    qs: req.query,
    json: req.body,
    headers: {
      'Oracle-Mobile-Extra-Fields': 'createdBy,createdOn'
    }
  };

  req.oracleMobile.rest.post(optionsList, function (error, response, body) {
    var message = error ? error.message : body;
    res.status(response.statusCode).send(message);
  });
});

optionsList Argument

You use the optionsList argument to pass request details in oracleMobile.rest calls, such as the URI, the body, and the headers. Here are some examples of the options that you can configure:

body

This option contains the body for a patch, post, or put request. The value must be a Buffer or a String unless OptionsList.json is set to true. If OptionsList.json is true, then the body must be a JSON-serializable object. See also the json option in this list.

headers

This option contains a list of HTTP headers. For example:

optionsList.headers=
{Content-Type : 'application/json;charset=UTF-8'};

Note:

When you use the json option, you do not need to provide the Content-Type header. For all other cases, when the request has a body, include this header and specify the charset.
json
This option can be used in two ways:
  • To hold a JavaScript object. In this case, when the request is sent, the object is converted to JSON and put in the HTTP body, and the Content-Type: application/json header is added automatically.

  • To indicate, by setting the value to true, that the optionsList.body value is a JavaScript object. In this case, when the request is sent, the optionsList.body value is converted to JSON and put in the HTTP body, and the Content-Type: application/json;charset=UTF-8 header is added automatically.

timeout

This option specifies the number of milliseconds to wait for a request to respond before terminating the request. If you don’t provide this option, then the timeout value defaults to the time out that’s specified by the Network_HttpRequestTimeout environment policy.

The value shouldn’t be greater than the Network_HttpRequestTimeout environment policy for the environment that the implementation is deployed to. Ask your cloud administrator for the value of this policy setting.

If the target URI is a connector, then the value should be greater than the Network_HttpConnectTimeout and Network_HttpReadTimeout policies for the connector. These values are displayed on the connector’s configuration page.

uri

This required option contains the URL fragment that uniquely identifies the API to call. For example:

/mobile/platform/storage/collections/coll1/objects

In addition to the options listed here, you can provide any of the options that are specified by the Request.js API. Go to the API documentation at https://github.com/mikeal/request and scroll down to the section entitled "request(options, callback)".

Learning About Platform, Custom, and Connector APIs

You can use the API catalog to learn about the platform, custom, and connector APIs. To access the API catalog, click icon to open the side menu to open the side menu and then select APIs.

  • To see the endpoints for a platform API, scroll to the bottom of the API Catalog, and then select the API.

  • To see the endpoints for a custom API or connector API, open a custom API, click Implementations, and then click Custom Code API Catalog. From the Show list, select Connector APIs or select Mobile APIs depending on the API type, and then select the API to view its endpoints.

In addition to the API Catalog, REST APIs for Oracle Mobile Cloud Service provides information about the platform APIs. For example, it provides cURL examples as well as details about request and response bodies and headers.