Using Apex REST Resources
To support Apex REST resources, Mobile SDK provides two classes: Force.ApexRestObject and Force.ApexRestObjectCollection. These classes subclass Force.RemoteObject and Force.RemoteObjectCollection, respectively, and can talk to a REST API that you have created using Apex REST.
Force.ApexRestObject
Force.ApexRestObject is similar to Force.SObject. Instead of an sobjectType, Force.ApexRestObject requires the Apex REST resource path relative to services/apexrest. For example, if your full resource path is services/apexrest/simpleAccount/*, you specify only /simpleAccount/*. Force.ApexRestObject also expects you to specify the name of your ID field if it's different from "Id".
Example
Let's assume you’ve created an Apex REST resource called "simple account," which is just an account with two fields: accountId and accountName.
1@RestResource(urlMapping='/simpleAccount/*')
2 global with sharing class SimpleAccountResource {
3 static String getIdFromURI() {
4 RestRequest req = RestContext.request;
5 return req.requestURI.substring(req.requestURI.lastIndexOf('/')+1);
6 }
7
8 @HttpGet global static Map<String, String> doGet() {
9 String id = getIdFromURI();
10 Account acc = [select Id, Name from Account
11 where Id = :id];
12 return new Map<String, String>{
13 'accountId'=>acc.Id, 'accountName'=>acc.Name};
14 }
15
16 @HttpPost global static Map<String, String>
17 doPost(String accountName) {
18 Account acc = new Account(Name=accountName);
19 insert acc;
20 return new Map<String, String>{
21 'accountId'=>acc.Id, 'accountName'=>acc.Name};
22 }
23
24 @HttpPatch global static Map<String, String>
25 doPatch(String accountName) {
26 String id = getIdFromURI();
27 Account acc = [select Id from Account
28 where Id = :id];
29 acc.Name = accountName;
30 update acc;
31 return new Map<String, String>{
32 'accountId'=>acc.Id, 'accountName'=>acc.Name};
33 }
34
35 @HttpDelete global static void doDelete() {
36 String id = getIdFromURI();
37 Account acc = [select Id from Account where Id = :id];
38 delete acc;
39 RestContext.response.statusCode = 204;
40 }
41 }With Mobile Sync, you do the following to create a "simple account".
1var SimpleAccount = Force.ApexRestObject.extend(
2 {apexRestPath:"/simpleAccount",
3 idAttribute:"accountId",
4 fieldlist:["accountId", "accountName"]});
5var acc = new SimpleAccount({accountName:"MyFirstAccount"});
6acc.save();You can update that "simple account".
1acc.set("accountName", "MyFirstAccountUpdated");
2acc.save(null, {fieldlist:["accountName"]);
3// our apex patch endpoint only expects accountNameYou can fetch another "simple account".
1var acc2 = new SimpleAccount({accountId:"<valid id>"})
2acc.fetch();You can delete a "simple account".
1acc.destroy();Force.ApexRestObjectCollection
Force.ApexRestObjectCollection is similar to Force.SObjectCollection. The config you specify for fetching doesn't support SOQL, SOSL, or MRU. Instead, it expects the Apex REST resource path, relative to services/apexrest. For example, if your full resource path is services/apexrest/simpleAccount/*, you specify only /simpleAccount/*.
1{ totalSize: <number of records returned>
2 records: <all fetched records>
3 nextRecordsUrl: <url to get next records or null>
4}Example
Let's assume you’ve created an Apex REST resource called "simple accounts". It returns "simple accounts" that match a given name.
1@RestResource(urlMapping='/simpleAccounts/*')
2global with sharing class SimpleAccountsResource {
3 @HttpGet global static SimpleAccountsList doGet() {
4 String namePattern =
5 RestContext.request.params.get('namePattern');
6 List<SimpleAccount> records = new List<SimpleAccount>();
7 for (SObject sobj : Database.query(
8 'select Id, Name from Account
9 where Name like \'' + namePattern + '\'')) {
10 Account acc = (Account) sobj;
11 records.add(new
12 SimpleAccount(acc.Id, acc.Name));
13 }
14 return new SimpleAccountsList(records.size(), records);
15 }
16
17 global class SimpleAccountsList {
18 global Integer totalSize;
19 global List<SimpleAccount> records;
20
21 global SimpleAccountsList(Integer totalSize,
22 List<SimpleAccount> records) {
23 this.totalSize = totalSize;
24 this.records = records;
25 }
26 }
27
28 global class SimpleAccount {
29 global String accountId;
30 global String accountName;
31
32 global SimpleAccount(String accountId, String accountName)
33 {
34 this.accountId = accountId;
35 this.accountName = accountName;
36 }
37 }
38}With Mobile Sync, you do the following to fetch a list of "simple account" records.
1var getSimple = function() {
2 console.log("## Trying fetch with apex rest end point");
3 var config = {
4 apexRestPath:"/simpleAccounts",
5 params:{namePattern:accountNamePrefix + "%"}
6 }
7 return Force.fetchApexRestObjectsFromServer(config);
8}