19 Creating Services for MAX

You can build a mobile app without having to write a single line of code using Oracle Mobile Application Accelerator (MAX). Using MAX’s intuitive UI, you can quickly develop an app to test a custom code API.

As you’ll see in Who Uses MAX?, MAX can be used by both developers and business users alike. Although the mobile apps built with MAX are created from custom code APIs, business users may have only a passing familiarity with REST. Because of this, the custom code APIs that are used to create a mobile app with MAX differ from those used by other mobile apps: instead of endpoints, they use resources, which are essentially endpoint definitions expressed in more tangible, user-friendly terms. To MAX users, these resources are known as business objects. Not only do these resources help MAX users understand how their app can use data, they also enable MAX to assist users in creating screens and interactions. You have a couple of options for creating an API with resources: you can create a custom API with JSON schemas for the endpoint requests and responses or, you can use the Express API builder, which creates methods and the JSON schema for you. See What are Resources? to find out more.

After you’ve defined the resources, you can make your API available to MAX by publishing it. Any API that you publish for use in MAX must include resources, not endpoint definitions. Because MAX has no concept of endpoints, it can’t discover them and therefore can’t surface your API for MAX users. To allow mobile apps running on smartphones via the MAX APP to access the API, you need to publish both the API and its implementation. If there are multiple environments, you must deploy the API and its implementation prior to publishing them. API Lifecycle describes the difference between publishing and deploying an API and provides instructions on how to do both. See What is MAX? to find out more about the MAX development environment and the MAX App.

What are Resources?

A resource expresses a collection of endpoints as a real-world object. In other words, the GET, POST, and PUT operations on the /incidents endpoint would simply be known as an “incident”. The resources that you create in MCS are surfaced as business objects in MAX. By selecting a business object, a business user can ultimately create an entire application flow that includes a list view that drills down to a detail screen along with create and update screens as well.

Note:

Before you read on, you should take a look at Exploring Services to find out about the Service Catalog, the Data Palette, the Data Mapper, and the QuickStart wizards.
In keeping with MAX's intuitive, no coding-required approach, the MAX user interface recasts APIs as services that group together the business objects. The resources that you define for a custom API’s endpoints in MCS are represented as business objects in MAX. To find out more, see Defining Endpoints. Business objects are comprised of sets of fields, which hold the data related to the underlying resource. Using the MAX Designer, business users populate UI components like forms and data visualization components (line charts, bar charts, and so on) using these fields. Because these fields are derived from REST endpoints (meaning they can for example, be read-only, or be manipulated by app users by accepting user input or updates), MAX uses them to populate screens. The resources themselves can also have create, read, update, and delete (CRUD) actions associated with them. They can also have relationships with one another, meaning that they can be peers, or have parent-child relationships.

How Do I Create Resources with the Express API Designer?

The Express API Designer has a set of task-specific tabs that help you create the fields, methods, and sample data for a resource. Within the context of the Express API Designer, a resource is a collection of endpoints. When you add a resource to your API, MCS creates a set of CRUD methods on these endpoints and constructs the JSON request and response schemas for you as well. You can find out more about creating these schemas on your own in How Do I Create Resources Using JSON Schemas?, but if you want to see the ones that MCS creates for you, click Export RAML (This is an image of the Export RAML icon.) to download a a RAML file to your system, or toggle between the designer and the RAML document by selecting Enter RAML Source Display Mode (This is an image of the Enter RAML Source Display Mode icon.).

Creating Resources

The Express API Designer steps you through creating an entire resource definition and its sample data, you can build the complete resource (and its sample data) even more quickly using the Create Resource wizard.
  1. Click the side menu (This is an image of the side menu icon.), choose Applications and then APIs.
  2. Click New API and then choose Express API.
    This is an image of the Express API option.
  3. Complete the New Express API dialog by adding the API’s name along with the display name and the description that will display in the Service Catalog in the MAX Designer. When you’re done, click Create.
    By completing this dialog, you open the Express API Designer. By default, the Express API Designer displays its General page, where you can the change the API name or description.
  4. Now you’re ready to add a resource. Click Resources in the left navbar, then click New Resource to open the Create Resource wizard.
    This is an image of the New Resource button.

    Note:

    Each resource added by clicking New Resource is a top-level resource, one that can’t be selected as a child resource.
  5. Describe your resource by adding a name, a display name, and a brief description. Don’t forget to enter a display name in plural form for the collection.

    Tip:

    Keep in mind that the names and description that you enter are displayed in the Data Palette in MAX.

    Resources typically have two GET methods: one that returns a single item of an object, and one that returns multiple items (a collection). If you select Also expose a collection of these resources, MCS creates both GET methods and labels them Find and List, respectively. If your API supports create actions (POSTs), you need to add a collection.

    Not all resources require both GET methods (or other methods that MCS creates for you, like POST, PATCH, and DELETE). You’ll be able to remove any methods you don’t want from the Express API Designer after you’ve finished creating the current resource.

    If you click Finish now to exit the wizard. The resource you created is saved and you can refine it in the Express API Designer later. You’ll have to manually add any fields you want to include from the Express API Designer.

  6. While you can create a resource and add its fields and sample data manually, you can build a complete the resource (and add its sample data) by first clicking Next and then adding JSON arrays or instances of sample data in the Sample Data page. This sample data is the mock data that helps you test the API. Within MAX, the mock data helps users visualize their app.
  7. If you don’t want to add sample data now, click Finish to exit the Create Resource wizard. You’ll be taken back to the Express API Designer, where you can add fields and sample data later on. Otherwise, click Next to review the fields created from the sample data.

    Click the Sample Data tab to review the sample date you previously entered. Don’t worry if field names or labels aren’t exactly what you want. You’ll be able to edit all these fields from the Express API Designer after you’re done creating the resource.

  8. Click Endpoints and review all the methods created for you. When you return to the API Designer, you can select the methods that you want your resource to use.
  9. Click Finish when you’re done.

After you’ve created your resource, you’re taken back to the Express API Designer so you can complete your resources by selecting the fields and methods you want to use. You’ll also be able to shape request and response the payloads for your methods. See Completing Your Resources.

To configure security for your API, export the RAML and then import into the Express API Designer.

Completing Your Resources

After you’ve created your resource, you can refine it in various ways, such as:

You can do all these things from the Overview tab on the Resources page. When you click Resources from the Express API Designer navbar (or when you click Finish from the Create Resource wizard), you’re taken to the Overview tab in the Express API Designer, which lets you refine your resources by doing the following:

  • Change the resource’s display name(s) and description.

  • Create reference or child relationships. You can learn more about peer and child relationships in Referenced Resources.

  • Toggle the Include Resource Collection option to allow (or prevent) the return of multiple items from a collection. When you select this option, the General tab displays the methods available to a collection: List (GET /items) and Create (a POST call on a collection).

    These methods display as hyperlinks that open pages for editing the method’s requests and responses. Shaping Payloads tells you more about editing methods.

Adding Additional Fields
  1. Click the Fields tab.
    For each resource, MCS creates a field called id. You can’t delete this field, whose role is described in Fields.
  2. If your resource needs more fields, click New Field and then complete the dialog by defining the field name and along with the display name and description that display in the MAX Service Catalog.
In addition to these display-related values, you also use this dialog to specify the format (string, integer, geolocation coordinates, and so on) expected by this field. By choosing the Reference field type, you can allow the field to reference the fields defined for a peer or child resource that’s selected from the Reference Resource list. You can find out more in Fields.
Shaping the Payload for Your Resource
With the resource complete (meaning that you’ve defined all of the possible fields for it), you’re ready to select the ones that are sent to, and returned from, the service. This is known as shaping the request and response payloads, which you can do as part of editing the methods.
  1. Click a link in the Methods tab to open the Edit Method page.
  2. Choose the request or a response type along with media type.
  3. Click the Shaped option and move the fields that you don't want to include in the payload from the Selected fields window to the Available Fields window.
    By default, all of the fields are included in the payload. See Methods to learn about custom methods and payloads.
  4. Click OK to save your changes.
See Shaping Payloads to find out about shaping data for different types of methods.
Adding More Sample Data
Using the Sample Data tab, you can add the mock data that helps you test your API and guide MAX users as they map field data. While MCS includes a row of sample data in the RAML document when you create fields manually for your resource, it may not reflect the data returned by your service. You can take a look at this sample data by toggling the RAML display mode option (This is an image of the RAML display view option.). An array of MCS-generated sample data might look like this:
[
                  {
                      "id": "id0",
                      "amount": "amount0",
                      "name": "name0",
                      "date": "date0"
                  },
                  {
                      "id": "id1",
                      "amount": "amount1",
                      "name": "name1",
                      "date": "date1"
                  },
                  {
                      "id": "id2",
                      "amount": "amount2",
                      "name": "name2",
                      "date": "date2"
                  }
              ]
Clicking New Row gets you started with populating your resource with sample data by opening the Create Sample Data dialog. Because this template lets you enter sample values for all of the fields that you’ve defined for the resource, your sample data stays in step with the field schema definition. While it’s possible that some fields may not have sample defined for them, the reverse will never happen. Creating the sample data is similar to creating fields in that you’re creating the data for the entire resource, not for a specific method. Instead, the payloads that you fashion using the Edit Method page ensures that the appropriate data is returned.
This is an image of the Create Sample Row dialog.
After you’ve added one row, you can quickly add others using the Sample Data tab’s Duplicate and Edit functions. To remove a row, select it and then click Delete.

Note:

MCS generates an ID value for you when you duplicate a row.

Referenced Resources

Your resources can reference each other as peers, meaning that they occupy the same level. For example, your API might include two resources that complement each other, but are distinct. For example, an API that returns CRM (Customer Relationship Management) data might have two such resources: Accounts and Opportunities. The Accounts resource includes a set of fields that describe different facets of an account, like the company name and location. The information returned for these fields may relate to, but doesn’t overlap, the information returned by Opportunities resource, whose fields return data that allow status meters to measure the opportunity’s win percent. Your API might include resources that reference each other in a different way, as a parent-child relationship. The Accounts resource, for example, might have a subsidiary (or nested) resource called Account Notes, which is wholly dependent on the Accounts resource. If you deleted the Accounts resource, you’d delete the Account Notes resource along with it.
This is an image of the top-level and child resources

You can include the fields from a referenced resource in the payloads. When the Opportunities resource references the Accounts resource, for example, its payload for the Find Opportunities’ 200 response includes account.id and other fields defined for the Accounts resource.
How Do I Reference a Resource?
To reference an resource:
  1. Click Resources.
    This is an image of the Resources icon.
  2. Click a resource.
    This is an image of the Resources.
  3. Click Add (This is an image of the Add icon.) and then choose a child or a parent resource:
    • Select a a resource from the list
      This is an image of the Resource Name list.
    • To reference a child resource, first click Add and then complete the Create Resource dialog. MCS will create a set of method definitions for the child resource. Next, choose the child resource from the Resource Name list.
  4. Click the Fields tab. MCS lists the resource with the fields. You can choose this resource (or other peer or child resources that you’ve reference in the API) for reference fields.
    This is an image of the Fields tab.
  5. Click the Methods tab and then click one of the links to open the Edit Method page.
    This is an image of the Methods tab.
    By clicking Response–200 in the Edit Method page, you can take a look at the referenced fields. They’re noted as resource.field name (like accounts.region, for example). See Shaping Payloads to find out more. The payloads for the POST and PATCH requests will include the reference object itself, not its individual fields. There are no fields (referenced or otherwise) for either GET request because they don’t include payloads.
    This is an image of the Edit Methods page.
  6. Click Save.
After you’ve made your API available to MAX by publishing it, take a look at the MAX Designer’s Service Catalog to see the various relationships between your resources.
This is an image of the Service Catalog.

Fields

Fields describe the different aspects of a resource. They are like properties: they describe the data they hold in terms of type (like a string, number, or reference) and format (date-time, URI, and so on). Fields can behave differently as well, depending on context (or more specifically, on the payload definition). The fields that populate list views in MAX are read-only, while the ones used in form-based create and update screens can accept user input.

The Fields tab lets you take inventory of the fields for a selected object. It’s where you can create a complete (or canonical) resource by defining all of the possible fields. After you’ve completed the resource, you can decide which methods can accept (and return) a subset of these fields by shaping the payloads in the Methods tab.

Tip:

Clicking Edit (This is an image of the Edit Field icon.) opens and closes the Field editor, where you can update the field display name, description, field type, and referenced resource. To delete a field, open the editor and then click Delete Field (This is an image of the Delete Field icon.).
MCS adds the id field for you when you create a resource. Because of its role as a UUID (universally unique identifier), this field acts as the primary key. You can’t delete this field, change its field type from a string, or change it from being a primary key, but by clicking Edit (This is an image of the Edit Field icon.), you can use field editor to change its display name and description to reflect the resource.

Methods

MCS creates a set of CRUD (Create, Read, Update, and Delete) methods for you when you create a resource. Using the Methods tab, you can select from among these methods, add new ones, and shape the request and response payloads.

Selecting Methods

While all of the methods are selected by default, they may not all apply to your resource. You can select the CREATE, POST, or PATCH methods as needed, but because each resource needs at least one GET endpoint (or two if it’s exposed as a collection), you can’t remove the GET methods.

Custom Methods

Custom methods (which are always POST methods) allow your resource to perform a task or server-side action that falls outside of the functions enabled by the default set of CRUD methods. For example, you can define a custom method that enables an upload action on an Image component. Using the Fix-It-Fast app as an example, you could define an action to close an incident that’s triggered by a swipe tile. Clicking New Custom Method opens the Create Custom Method dialog that lets you define a custom method on a nested resource (which MCS adds for you). After you’ve created the method, you can use the Edit Method page to shape the payload of its request body and add its Success (2xx) or Failure (5xx) responses. To find out more, see Shaping Payloads.
Description of custom_method_dialog.png follows
Description of the illustration custom_method_dialog.png
You can delete a custom methods, but you can’t delete any of the default set of methods that MCS creates for you.
Shaping Payloads
The Edit Methods page not only lets you change the method’s display name and description, but also allows you to shape its request and response bodies by including, or excluding, the fields that filter the returned data and populate the create, update, list and detail screens. You can open this page by clicking the method links in the Overview or Methods tabs for a selected resource, or from the read-only list of all the methods defined for the APIs that display in the Endpoints tab.

GET Payloads

There are no request bodies for GET methods, just responses. The Edit Methods page lets you select filtering criteria for the data returned for a list or a detail. In MAX, these surface as query parameters.
For 200 responses, MCS adds all of the fields that you’ve created for the resource per the default option, Complete. While you can choose this option for detail screens, you might want to pare down the payload for a list screen by clicking the Shaped option. You can then shuttle the fields that you don’t want from the Selected window to the Available window. When the subset of fields in the Selected window suits your needs, click OK.

POST and PATCH Payloads

For POST and PATCH requests, you shape the payload with the fields that will be sent to these methods to create or update an item.

Media Types for Request and Response Bodies

As part of the payload configuration, you can set the content type as application/json, application/octet-stream, or image/*. Use application/octet-stream for custom methods that support images.

Read-Only Fields
For POST and PATCH fields, you can create read-only fields by shaping the request and response bodies. By including a field in both the request and response payloads, you allow it to accept user input. By including it in the response body only, you confine the field to read-only display. By default, MCS adds the ID field to the response body because this field typically holds a server-generated value that users shouldn’t edit. Other than the ID field, there may be other cases where your request and response bodies don’t align. For example, to ensure that users can’t inadvertently compromise the integrity of your data by updating the date field in an edit screen, you’d first add the field to the response payload’s Selected window and then update the request payload by shuttling the date field from the Selected window to the Available window.

Sample Data

The Sample Data tab displays all of the data used by a resource for any purpose. In other words, the data is not specific to any method. As noted in Creating Resources, you can add this data manually, or derive it from the instances and arrays of sample data that MCS uses to generate the both the resource’s fields and the resource itself.
By adding a single JSON instance similar to the following, you can complete the resource by defining key-value pairs.
{                "desc":"Northern California Data Center",
                 "region":"NA",
                 "winpercent":95,
                 "salesstage":"Closing",
                 "revenue":550000,
                 "products":"EXA-Data2, A420 Cable, I5 Routers, A10 Switchees",
                 "expectedclose":"2016-07-09T02:40:25.328",
                 "createddate":"2015-09-05T00:00:00.000"
                 }

Tip:

Because MCS creates the id field for each resource, you don’t need to include it your JSON.
MCS does more than just create fields from the JSON: it infers their data types as well. From the “revenue”: 550000, key-value pair in the above sample, for example, MCS can interpret the field type as an integer rather than as a string.
You can create your top-level resources using this data-first approach. By nesting instances, you can create multiple top-level resources and establish reference relationships for them. The following example shows how nesting an instance creates a peer resource called Account:
{                "desc":"Northern California Data Center",
                 "region":"NA",
                 "winpercent":95,
                 "salesstage":"Closing",
                 "revenue":550000,
                 "products":"EXA-Data2, A420 Cable, I5 Routers, A10 Switchees",
                 "expectedclose":"2016-07-09T02:40:25.328",
                 "createddate":"2015-09-05T00:00:00.000",
                 "account":{"name":"Acme Corporation",
                            "website":"http://www.acme.com",
                            "region":"IN",
                            "address":"100 Main St",
                            "city":"San Carlos",
                            "state":"CA",
                            "country":"USA",
                            "formattedAddress": "100 Main St, San Francisco, CA, USA"
                           }
                }
Using arrays, you can create top-level resources along with multiple rows of sample data:
[
                  {
                      "desc": "Anvils",
                      "region": "NA",
                      "winpercent": 30,
                      "salesstage": "appointment",
                      "revenue": "35000",
                      "expectedclose": "2016-07-09T02:40:25.328",
                      "account": {
                          "name": "Acme"
                      }
                  },
                  {
                      "desc": "Horns",
                      "region": "SA",
                      "winpercent": 90,
                      "salesstage": "closing",
                      "revenue": 25000,
                      "expectedclose": "2016-07-09T02:40:25.328",
                      "account": {
                          "name": "Road Runner"
                      }
                  },
                  {
                      "desc": "Bank Vaults",
                      "region": "EU",
                      "winpercent": 25,
                      "salesstage": "prospect",
                      "revenue": 15000,
                      "expectedclose": "2016-07-09T02:40:25.328",
                      "account": {
                          "name": "Coyote"
                      }
                  }
              ]

Note:

You can only create top-level resources with sample data, so can’t add a child resource by nesting an array. Referenced Resources tells you how to add child resources.

As noted in Completing Your Resources, you can add or remove fields, or change the field display name and data type using the field editor. Because you need to define a value for each key, your resource’s GET methods will always return a full set of data. Because this may not reflect real-world scenarios, you can edit your data using the Sample Data tab. To find out more, see Adding More Sample Data.

What is MAX?

Before we delve into business objects, here’s a birds-eye view of MAX. MAX is a web-based development environment that has tools that let you build your UI and bind it to data using a combination of drag-and-drop gestures and minimal configuration. MAX also lets you test your app and, when you’re finished, publish it. If you want to build an app to test a custom code API, you can start in right away. You just need to publish your API first, as described in Publishing a Custom API.

To get you started, MAX helps you build the first page of your app by stepping you through a wizard. This wizard lets you name your app and pick the basic layout for the first page, like a list view or a dashboard. By completing this wizard, you’ve set the basic structure for your app.

MAX then opens the Designer, where you can complete your app. At this point, your app is viable even though it’s not yet displaying your data – you can run it on a device and use its built-in navigation functions, like opening and closing the main menu. But if you’re using MAX to test an API or develop one, you’d probably like continue on by building up the first page with UI components and then use the resources (which are known within MAX as business objects) that you’ve created. The Designer lets you choose from a set of UI components that best suits your data. It also lets you realize your application flow by configuring how your screens (and the various components within them) interact with one another and respond to users’ swipe or tap gestures. MAX guides you through adding data to your app using both mock data and live data.

At any point during development, you can preview how your app handles live data using the Designer’s test simulator. When you’re done, you can close the simulator and return to your work. To get an even better idea of the user experience, you can test your app on a smartphone using the MAX App. It allows all of the apps that you create (both test and production versions) to run on a phone and access its services, such as the phone dialer and e-mail.

Note:

You need to publish your custom code API and its implementation to allow it to run within the MAX App. To do this, follow the steps in Publishing a Custom API .
You can learn more about the MAX App along with information on building, testing, and distributing apps in Designing Your App.

Note:

You need to configure the MAX user accounts correctly to let users test their apps and, when they’re ready to distribute them to users, publish them. Read Mobile Users for MAX to find out more.

Who Uses MAX?

There are two types of MAX users: MCS developers (mobile app developers and service developers), who use MAX as part of their testing and development of custom code APIs, and business users, who create line-of-business (LOB) apps. To create these apps, MAX users don’t need to know platform-specific languages, nor do they even need to know anything about MCS in particular: a business user may be completely unaware that a mobile backend manages the app that he’s building, or that a custom code API enables his app to use enterprise data.

These users access MAX in different ways: MCS developers access MAX from within MCS by clicking Applications > Mobile Apps. Because they focus on building apps (rather than the backend services that these apps consume), business users access MAX directly after they log into MCS. Unlike MCS developers, business users are MAX-only users: they’re granted the BusinessUser role, so they never see MCS (and can't log into it). You can find out how MAX roles are permissions are allocated in Mobile Users for MAX.

How Do I Enable App Users to Upload Images?

The MAX Image component, when bound to a business object, lets app users upload images from their phones.
To support this functionality, your resources need the following:
  • An image path field. In the MAX Designer, users map this field as the source for the Image component.

  • A custom method. Like all custom methods, this is a nested POST method. In this case, it might be something like POST /employee/{id}/uploadPhoto.

    Because you’re sending binary streams through this API, you need to select application/octet-stream as the media type for this method’s request body.
After you surface your API in the MAX Designer by publishing it, you can configure an Image component with the image path field and upload method.
  1. In the Data Mapper, use the image path field as the image source.
  2. In the Properties Inspector for the Image component, clear the Read Only option to allow users to add their own images. When you do this, MAX superimposes an edit overlay (This is an image of the Edit overlay.) on the image component.
    Changing this property also allows the MAX Designer to detect the actions that support binary streams and populate them in the Data tab’s Image Update Actions menu.

Tips for User-Friendly Business Objects in MAX

You can help business users pick services and map data by adding metadata in MCS.

The metadata that you enter in MCS... ...Is surfaced here in MAX
The API metadata entered in the General Page of the API Designer:
  • API Display Name

  • Short Description

  • icon

The service name and description in the Service Catalog:
The endpoint description and display name for top-level resources entered in the Endpoints page of the API Designer:
The property members of the schema definition (including the description key) that are defined for the GET response:
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "incident",
  "title": "Incident Detail",
  "type": "object",
  "properties": {
    "id": {
       "type": "string",
       "description": "Unique incident ticket number"
    },
    "problem": {
       "type": "string",
       "description": "Short description of the incident"
The display name and description for endpoint methods entered in the Endpoints page of the API Designer: The Actions tab of the Data Palette:
The title key in the schema:
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "patch-incident",
  "title": "Update Incident",
  "type": "object",
   
...

     }
The Configure Action page of the Properties Inspector:
GET method Query definitions for the request parameters entered in the Endpoints page of the API Designer: The Query page of the Add Data QuickStart and the Data Mapper:
The $ref definition that point to other top-level resources in the GET response schema definition.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "incident",
  "title": "Incident Detail",
  "type": "object",
  "properties": {
   ...

    "customer": {
      "$ref": "incident-customer",
      "title": "Details of customer who logged the incident."
    },
    "location": {
      "$ref": "IncidentLocation",
      "title": "Location where the incident occurred"
    }
The display name and description for endpoint methods entered in the Endpoints page of the API Designer: The Related Objects tab of the Data Palette (under Reference Objects):
The display name and description for nested resources that are entered in the Endpoints page of the API Designer: The Related Objects tab of the Data Palette (under Child Objects):
The property members of the schema definition (including the title key) that are defined for the GET response for a nested object.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "incident-activity",
  "title": "Incident Activity",
  "type": "object",
  "description": "A single activity reported on an incident.",
  "properties": {
      "incidentId": {
        "type": "string",
        "description": "Incident Identifier that this activity record belongs to"
      },
      "firstName": {
         "type": "string",
         "description": "The first name of the person who created the activity"
      },
      "lastName": {
         "type": "string",
        "description": "The person's last name"
      },
The Data Source page Data pages of the Data Mapper and the Add Data QuickStart for a detail screen.
Mock data defined for requests and responses in the API Designer:
{
  "id": "inc-201",
  "problem": "Incident New",
  "description": "I learned that beneath my goody two shoes lie some very dark socks.",
  "createdOn": "2015-08-18",
  "lastUpdatedOn": "2015-08-20",
  "picture": "/builtin/images/broken-water-heater.png",
  "status": "open",
  "priority": "medium",
  "customer": {
    "id": "cus-101",
    "username": "julie.simpson",
    "firstName": "Julie",
    "lastName": "Simpson",
    "mobile": "6505067000",
    "home": "5105552121",
    "email": "julie.simpson@springtime.com"
  }

Video: An Introduction to Mobile Application Accelerator (MAX)

To see how you can build, test, and publish mobile apps using MAX, take a look at this video:

How Do I Create Resources Using JSON Schemas?

As an alternative to the Express API Designer, you can build an API with resources using the API Designer.

To enable this API to surface in the MAX Designer, you need to define JSON schema definitions on its endpoints. These schema define the resources, their fields, and their methods. You can build these schemas from scratch, or you can import a RAML file (even the one generated by the Express API Designer). To get a comprehensive view of creating an API for MAX, one that demonstrates how to add JSON schemas to the endpoints, go through the tutorial, Shaping MCS APIs for MAX.

Tip:

Before you read on, take a look at the JSON schema specification.

How Do I Define Fields?

To create fields, you need to define JSON schemas for the endpoint requests and responses. These schemas define how and where the fields appear in the MAX UI.

These schemas define the fields as property members, like name and website in the following example:
{  
"$schema": "http://json-schema.org/draft-04/schema#",
  "id": "account",
  "type": "object",
  "properties": {
    "name": {
      "id": "name",
      "type": "string"
    },
    "website": {
      "id": "website",
      "type": "string"
    },
…
} 
They also designate the kind of data that the fields can hold and the kind of user input that they allow. Because these schemas are written for GET, POST, PATCH, and PUT endpoints, the field behavior takes its cues from the method defined on the resource. To find out how to add a JSON schema using the API Designer, see Providing a Schema.
Defining Field Types, Formats, and Enums

Define the kind of data that your field holds by using combinations of the JSON schema type, format, and enum keywords.

Some things to keep in mind:
  • Define enumerated values (enums) in the schema so that business users won’t have to enter them as fixed values in the MAX Designer. For example:
    "region": {
          "id": "region",
          "type": "string",
          "enum": ["IN", "NA", "SA", "AP", "EU"]
    
  • When defining the field format for a date, we recommend UTC (Coordinated Universal Time):
    "properties": { 
              "lastUpdatedOn": {
                "type": "string",
                "format": "date-time",
                "description": "When the incident was last updated"
              },
    

Field Formats

You can add constraints on the values that users enter by adding validators like required, minlengnth, maxLength, minimum, and maximum to the property:
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "postOpportunity",
  "type": "object",
   "allOf": [
    {"$ref": "opportunity"}
  ],
  "required": [
    "desc",
    "region"
  ]
}
For fields that require input in a special format like a phone number, use the pattern keyword and then define a regular expression:
"pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$"

Example 19-1 Taking a Look at Properties in the JSON Schema

In the following example, a schema called account that defines of the base fields for a business object. Notice the type keyword defines the kind of data allowed in each field (string).

{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "account",
  "type": "object",
  "properties": {
    "name": {
      "id": "name",
      "type": "string"
    },
    "website": {
      "id": "website",
      "type": "string"
    },
    "region": {
      "id": "region",
      "type": "string",
      "enum": ["IN", "NA", "SA", "AP", "EU"]
    },
    "address": {
      "id": "address",
      "type": "string"
    },
    "city": {
      "id": "city",
      "type": "string"
    },
    "state": {
      "id": "state",
      "type": "string"
    },
    "country": {
      "id": "country",
      "type": "string"
    }
  }
}  
For a base object, the properties don’t include an ID (defined as aid in the following example). IDs aren’t present when POST calls create records. Instead, the ID is assigned by the server. The following schema defines a field for the account ID called aid, which allows data to be returned by a GET call. In addition to the account ID, this schema allows all of fields defined for the account schema as well, because it includes the allOf keyword and assigns account as the pointer to the ref keyword.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "getAccount",
  "type": "object",
  "allOf": [
    {"$ref": "account"}
  ],
  "properties": {
    "aid": {
      "id": "aid",
      "type": "string"
    }
  }
}

Defining Child Objects

By defining a schema for a nested resource, you can create a child object. Unlike a reference (or peer) object, which is the MAX representation of a top-level resource, a child object can’t exist on its own. It only has meaning within the context of its parent business object.

The following schema defines a child object for the nested resource, /accounts/{aid}/opportunities. In this example, the canonical (or base) link returns the child object’s resource (opportunities). The links keyword gives the location for the child resource, opportunities.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "getAccountOpportunities",
  "type": "array",
  "items": {
    "$ref": "getOpportunities"
  },
  "links": [
  {
    "rel": "canonical",
    "href": "/opportunities?aid={aid}"
  }]  
}

Tip:

You can have different links defined in an array.
This example shows a schema on another nested resource, /opportunities/{oid}/notes to return the notes for a specific opportunity. In this case, the nested resources defines a grandchild object using the ID (oid) as part of the canonical link:
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "getOpportunityNotes",
  "type": "array",
  "items": {
    "$ref": "getNotes"
  },
  "links": [
  {
    "rel": "canonical",
    "href": "/mobile/custom/CRM/notes?oid={oid}"
  }]  
} 

Defining Fields for List, Details, Create, and Update Screens

In blanket terms, field behaviors can be described as summary, creatable, and updatable. In other words, whether fields can accept user input, like those in create or update screen, or appear as a read-only field in a list component.

These behaviors – and their related collection, create, read, update, and delete actions – are based on endpoints. By defining schemas for an endpoint’s request and response, you tell MAX how it can use these fields to populate the different types of screens created by the QuickStarts.

Every business object needs at least one endpoint. Some might require more than one. For example, you can define GET and POST method on a top-level resource (like /employees). Its GET method allows users to return all of the fields defined in the schema for the response. The schema defined for the POST method’s request defines the fields that can be used to create an item. To return a specific item, define a GET method on a nested resource (/items/{id}).

Note:

In MAX, POST methods are always used for fields used for create actions. Read actions are always GET methods.
Field Behavior Description Used in These MAX Components Method Tips
Collection Returns multiple items (or records) of the object. Calls GET on the collection resource (/items) to return all fields. See Collection Actions to find out more.
  • List Components

  • DVT Components

GET Specify the fields that you want to include in the schema for a collection endpoint. Add mock data field values for the request and the response.
Read Gets a single item of the object. Calls GET on the item resource (/items/{id}) to return the properties for an item. An object can be a singleton, in which case this calls GET on the item resource (/item). See Collection Actions to find out more. Detail Screen (read-only fields in a Form component) GET  
Create Creates a single item of the object. Calls POST on the collection resource (/items) with a request body that contains all of the creatable fields (which can be either required or optional), along with the user-provided values. This returns the new object with its new unique ID (which can be used subsequently in a read action). See Create Actions to find out more. Create Screen (form fields) POST Specify the fields that should be included in Create screens in the schema. Add mock data field values in the request and response.
Update Updates a single item of the object. Calls PATCH on the item resource (/items/{id}) with one or more updatable properties. See Update Actions to find out more. Edit Screen (form fields) PATCH (and sometimes, PUT) Specify the fields that users can update in the schema. Provide mock data for the field values for the request and response. We recommend using the PATCH method because it updates the server with only the fields that have been modified. See Using the PUT Method for Update Actions to find out more.
Delete Deletes a single item of the object. Calls DELETE on the item resource (/items/{id}). See Delete Actions to find out more.   DELETE  
Collection Actions

Typically, collection actions are based on two different GET methods.

One endpoint returns a list of multiple items of the object using the top-level resource. The other returns a particular item and uses a nested resource. Together, these two endpoint definitions represent a single resource that supports both the collection and read actions. This example shows a schema for the response for collection action. In this case it’s a GET method on the top-level resource, /accounts.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "getAccounts",
  "type": "array",
  "items": {
		"properties": {
		    "aid": {
		      "id": "aid",
		      "type": "string"
		    },
            "name": {
			    "id": "name",
				"type": "string"
    		},
		    "region": {
		      "id": "region",
		      "type": "string",
		      "enum": ["IN", "NA", "SA", "AP", "EU"]
		    },
		    "city": {
		      "id": "city",
		      "type": "string"
		    },
		    "state": {
		      "id": "state",
		      "type": "string"
		    },
		    "country": {
		      "id": "country",
		      "type": "string"
		    }
        }
  }
}
This example shows the schema for the response of a read action, defined for a GET action on a nested resource (/accounts/{aid}):
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "getAccount",
  "type": "object",
  "allOf": [
    {"$ref": "account"}
  ],
  "properties": {
    "aid": {
      "id": "aid",
      "type": "string"
    }
  }
}

Defining a Collection Using a Single Resource

You can create a resource that returns a list of items using a GET endpoint on a single resource. In this case (which is more the exception than the rule), there isn’t an additional endpoint for retrieving an individual item. In the following example, the Analytics resource has a collection action that returns a list of metrics (GET /stats). However, it does not use an endpoint that points to a specific resource (like GET /stats/{sequence}) to return an individual metric. The JSON response can be an array or an object. Objects include information about the data set, such as the number of items in the set, a token for the next set of items, and so on.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "stats",
  "title": "Analytics",
  "type": "object",
  "properties": {
    "metrics": {
      "type": "array",
      "description": "Metrics are individual measurements related to incident activity, techncian performance",
      "items": {
        "type": "object",
        "properties": {
          "month": {
            "type": "string",
            "description": "Date Dimension for which a data point is provided"
          },
          "technician": {
            "type": "string",
            "description": "Technician for whom the data is provided."
          },
          "radius": {
            "type": "number",
            "description": "radius in miles from the technician location, where incidents were reported."
          },
          "incidentsAssigned": {
            "type": "number",
            "description": "Incidents Assigned to Technician"
          },
          "incidentsClosed": {
            "type": "number",
            "description": "Incidents Closed by Technician"
          }
        }
      }
    }
  }
}

Note:

MAX can only detect objects that have one top-level array. MAX can't detect the primary collection when an object has more than one top-level arrays like metrics2 in the following snippet. In cases like this, the MAX can't make this collection available for data mapping.
{
  "count": 2,
  "metrics1": [
      {...}
  ],
  "metrics2": [
      {...}
  ]
}
Create Actions

You can add a create action by defining a POST method. In MAX, the POST method is the only way to enable create actions.

Having a POST method enables MAX to populate create screens with fields that allow user input (creatable fields). If a business object doesn’t have a POST method, then app users won’t be able to create items. Define the creatable fields in the JSON schemas for both the POST request and response. The following example shows a schema for the POST request called postAccount that defines creatable fields from the referenced account schema. Some of the fields returned from the account schema are optional, but in this schema, the name and region are designated as required fields; app users can’t create a new item without defining them.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "postAccount",
  "type": "object",
   "allOf": [
    {"$ref": "account"}
  ],
  "required": [
    "name",
    "region"
  ]
}
In addition to these required fields, the allOf keyword allows app users to add values into any of the fields defined in the account schema (shown below) to create new items. While the name and region fields (which are also defined in the account schema) are required, the other fields are optional. See also Defining Field Types, Formats, and Enums to find out more about using the allOf keyword.
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "account",
  "type": "object",
  "properties": {
    "name": {
      "id": "name",
      "type": "string"
    },
    "website": {
      "id": "website",
      "type": "string"
    },
    "region": {
      "id": "region",
      "type": "string",
      "enum": ["IN", "NA", "SA", "AP", "EU"]
    },
    "address": {
      "id": "address",
      "type": "string"
    },
    "city": {
      "id": "city",
      "type": "string"
    },
    "state": {
      "id": "state",
      "type": "string"
    },
    "country": {
      "id": "country",
      "type": "string"
    }
  }
}

Read Only Fields

To create read-only (non-editable) fields in a form, define fields in the JSON schema for the POST response that have no counterparts in the POST request schema. In the following table, the getAccount schema, which is defined for the POST response, includes the aid field, which holds the server-generated ID for an account. Because this is a read-only value, one which app users shouldn’t update, it’s not included in the field definitions of the POST request schema, postAccount, or the account schema that it references.
Response Schema Request Schema
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "getAccount",
  "type": "object",
  "allOf": [
    {"$ref": "account"}
  ],
  "properties": {
    "aid": {
      "id": "aid",
      "type": "string"
    }
  }
}
{
  "$schema": "http://json-schema.org/draft-04/schema#",
  "id": "postAccount",
  "type": "object",
   "allOf": [
    {"$ref": "account"}
  ],
  "required": [
    "name",
    "region"
  ]
}

Content Types for Creatable Fields

At runtime, MAX mobile apps return the content types specified in the POST endpoint, which can be application/json or application/x-www-form-urlencoded. You can specify application/x-www-form-urlencoded as the content type for a creatable field in the POST request, but also specify application/json as the content type for the read only fields returned by the response.

Update Actions

You can allow users to update a field's value by defining a JSON schema on a PATCH endpoint.

Schemas for PATCH endpoints enable MAX to populate edit screens (and other forms) with updatable fields. When forms are modified using PATCH, only the fields that users have updated are sent to the server, not the entire object.

Note:

When you define your PATCH endpoint, always specify the content in the request body as type as application/json instead of the JSON patch format (application/json-patch+json).
Using the PUT Method for Update Actions

In addition to the PATCH method, you can make fields editable by defining a JSON schemas for the requests and responses of a PUT method.

Although you can use both PUT and PATCH for update actions, keep in mind that the PUT method replaces all of the fields defined for a schema object (even if none of them have been modified). That means that the request payload must include the entire object. The request payload for the PATCH method, on the other hand, includes only the fields that have changed. Because of this, we recommend using PATCH (if the service supports it, that is). That said, use the PUT method if the service doesn’t support the PATCH method.

Delete Actions

The delete action is defined for an object. It enables users to remove an entire record, not just a field.

You can define a DELETE method on a nested resource like /accounts/{aid}, for example. If a resource can’t be removed (and therefore doesn’t support the DELETE method), then you can’t define a delete action.

Custom Actions

In addition to the CRUD actions, resources can also have custom actions that require custom code, transactional semantics, or unique processing on the objects.

In general, custom actions don’t return a payload. Instead, they perform server-side tasks and return success and failure responses.

Keep the following in mind when you create a custom action:
  • Use POST methods for custom actions.

  • Create the POST method for a nested resource like /incidents/{id}/closeIncident.

  • If needed, define a request body for the POST method.

  • Use a JSON hyper-schema links property to define the sub-resource. For example:
    {
        "$schema": "http://json-schema.org/draft-04/schema#",
        "id": "incident",
        "title": "Incident Detail",
        "type": "object",
        "properties": {...},
        "links": [
          {
            "rel": "self",
            "title": "Incident",
            "href": "/incidents/{id}",
            "method": "GET",
            "targetSchema": {"$ref": "incident"}
          },

Creating Mock Data for the MAX UI

Creating mock data for the fields defined in your JSON schemas help guide business users when they map data. When you define these values, be sure that they align with the fields that you’ve defined in your schema.

Note:

Take care when you define your mock data, because MCS doesn’t verify mock data against a schema.