NexJ Logo

Developing forms using REST APIs

You can include the "RestV2 API Infrastructure" (restapi) mixin model in your project and then develop forms for external systems using the REST APIs provided by NexJ Systems.

For information about implementing REST API v2, see Enabling and configuring REST API v2.

HTTP requests

You can use the following HTTP request methods in your code to consume, write to, or delete application server data for forms, and send your requests to the following resource endpoints:

HTTP request method descriptionsRequest typeResource endpointsSample request bodyExample
Read all flowsGET<HTTP URL>/channel/rest:REST/flowsNot applicable

http://localhost:7080/nexj/channel/rest:REST/flows

Read a flow using its string IDGET<HTTP URL>/channel/rest:REST/flows/{stringID}Not applicable

http://localhost:7080/nexj/channel/rest:REST/flows/10F33A2F285B154171BB8D95A7E1AC0E26

Read all flow templatesGET<HTTP URL>/channel/rest:REST/flowTemplatesNot applicablehttp://localhost:7080/nexj/channel/rest:REST/flowTemplates

Read a specific version of a flow template by its alternate key

GET<HTTP URL>/channel/rest:REST/flowTemplates/{templateName.templateVersion}Not applicable

http://localhost:7080/nexj/channel/rest:REST/flowTemplates/sampleFlow.2

For example, if there are two templates named "sampleFlow," versioned 1 and 2 respectively, the response will be version 2 of template "sampleFlow."

Read the latest version of a flow template by its alternate keyGET<HTTP URL>/channel/rest:REST/flowTemplates/{templateName}

Not applicable

http://localhost:7080/nexj/channel/rest:REST/flowTemplates/sampleFlow

For example, if there are two templates named "sampleFlow," versioned 1 and 2 respectively, the response will be version 2 of template "sampleFlow."

Create a flow associated with the latest version of a specific templatePOST<HTTP URL>/channel/rest:REST/flows
{
   "template": "sampleFlow",
   "isTransient": "false",
   "status": "PROCESSED"
}

The template key is a required key, which is the name and alternate key of the template.

http://localhost:7080/nexj/channel/rest:REST/flows

The sample request body creates a flow associated with the latest version of template "sampleFlow," when isTransient is set to false, and status is set to PROCESSED.

Create a flow associated with a specific templatePOST<HTTP URL>/channel/rest:REST/flows
{
   "template": "sampleFlow.2",
   "isTransient": "false",
   "status": "PROCESSED"
}

The template key is a required key, which is the name and alternate key of the template.

http://localhost:7080/nexj/channel/rest:REST/flows

The sample request body creates a flow associated with version 2 of the template "sampleFlow," when isTransient is set to false, and status is set to PROCESSED.

Create a specific version of a flow templatePOST

<HTTP URL>/channel/rest:REST/flowTemplates

The client-timezone key is required in the request header, for example: "client-timezone":"Europe/London"


{
   "name": "sampleFlow",
   "version": "2",
   "dslType": "scm",
   "bind": "Person"
}

The "name" key is a required key.

http://localhost:7080/nexj/channel/rest:REST/flowTemplates

The sample request body creates version 2 of template "sampleFlow," when the dslType set to scm, and bind is set to Person.

Create a new version of a flow templatePOST

<HTTP URL>/channel/rest:REST/flowTemplates

The client-timezone key is required in the request header, for example: "client-timezone":"Europe/London"

{
   "name": "sampleFlow",
   "dslType": "scm",
   "bind": "Person"
}

The "name" key is a required key.

http://localhost:7080/nexj/channel/rest:REST/flowTemplates

The sample request body creates version 3 of template "sampleFlow," when dslType set to scm, and bind is set to Person.

Update a specific flowPUT

<HTTP URL>/channel/rest:REST/flows/{stringID}

The "$commit-hash" is required in the request body of PUT. It can be obtained from the response of a GET request to the same URL.

The client-timezone key is required in the request header, for example: "client-timezone":"Europe/London"

{
   "$commit-hash": 163004577,
   "status": "PENDING"
}

http://localhost:7080/nexj/channel/rest:REST/flows/10F33A2F285B154171BB8D95A7E1AC0E26

The sample request body updates the status of the flow to PENDING.

Update a specific flow templatePUT

<HTTP URL>/channel/rest:REST/flowTemplates/{templateName} or 

<HTTP URL>/channel/rest:REST/flowTemplates/{templateName.templateVersion}

The $commit-hash is required in the request body of PUT. It can obtained from the response of a GET request to the same URL.

The client-timezone key is required in the request header, for example: "client-timezone":"Europe/London"

{
   "$commit-hash": 1796111967,
   "dslType": "NJS"
}

http://localhost:7080/nexj/channel/rest:REST/flowTemplates/sampleFlow

When the sample request body is sent to the above URL, the dslType of the latest version of the template "sampleFlow" will be updated to NJS.

http://localhost:7080/nexj/channel/rest:REST/flowTemplates/sampleFlow.2

When the sample request body is sent to the the above URL, the dslType of version 2 of the template "sampleFlow" will be updated to NJS.

Delete a flow using its string IDDELETE<HTTP URL>/channel/rest:REST/flows/{stringID}Not applicablehttp://localhost:7080/nexj/channel/rest:REST/flows/10F33A2F285B154171BB8D95A7E1AC0E26
Delete a specific version of a flow template by its alternate keyDELETE<HTTP URL>/channel/rest:REST/flowTemplates/{templateName.templateVersion}Not applicable

http://localhost:7080/nexj/channel/rest:REST/flowTemplates/sampleFlow.2

Version 2 of template "sampleFlow" will be deleted.

Delete the latest version of a flow template by its alternate keyDELETE<HTTP URL>/channel/rest:REST/flowTemplates/{templateName}Not applicable

http://localhost:7080/nexj/channel/rest:REST/flowTemplates/sampleFlow

For example, if there are two templates named "sampleFlow," versioned 1 and 2 respectively, version 2 of template "sampleFlow" will be deleted.

Read selection options for flow "status"GET<HTTP URL>/channel/rest:SelectionOptions/flows/statusNot applicablehttp://localhost:7080/nexj/channel/rest:SelectionOptions/flows/status
Read the schema model of flowGET<HTTP URL>/channel/rest:OpenAPI/en/schemas/flow.jsonNot applicablehttp://localhost:7080/nexj/channel/rest:OpenAPI/en/schemas/flow.json
Read the schema model of flow templateGET<HTTP URL>/channel/rest:OpenAPI/en/schemas/flowTemplate.jsonNot applicablehttp://localhost:7080/nexj/channel/rest:OpenAPI/en/schemas/flowTemplate.json
Link to the full OpenAPI specification in JSON format.Not applicable<HTTP URL>/channel/rest:OpenAPI/en/openAPI.jsonNot applicablehttp://localhost:7080/nexj/channel/rest:OpenAPI/en/openAPI.json
Link to SwaggerUINot applicable<HTTP URL>/rest:SwaggerUI.htmlNot applicable

http://localhost:7080/nexj/rest:SwaggerUI.html

The full list of endpoints, parameters, response codes, and model fields are provided in the SwaggerUI page.

Due to current REST V2 limitations, the request body only supports string values. As a result, the following actions are not supported for POST and PUT:

  • When creating or updating a flow using POST or PUT, specifying "globals" for initializing values in a flow.
  • When creating or updating a flow template using POST or PUT, specifying a DSL definition.

For example, if a form is bound to a Know your Customer (KYC), you cannot pass in a contactId to initialize the For field through REST.

Responses

The following information shows examples for the responses that are returned to the client (browser) for requests:

GET the latest version of a flow template {<flowTemplateName>}: http://localhost:7080/nexj/channel/rest:REST/flowTemplates/{<flowTemplateName>}

{
   "$commit-hash": 1758539092,
   "flowCount": 2,
   "summaryStringAuditDates": "Created nexjsa 5/5/20 10:43 AM, Edited nexjsa 5/7/20 9:53 AM",
   "dsl": "(bp:flow\r\n  ... (bp:page KYC (: caption \"KYC\") (: number \"6\") (: visible (@ question noSIN)))\r\n   )\r\n",
   "importMode": false,
   "createAuthorAlias": "nexjsa",
   "createTime": "2020-05-05T14:43:42Z",
   "name": {<flowTemplateName>},
   "createUserAlias": "nexjsa",
   "createdByText": "Created by nexjsa on 5/5/20 10:43:42 AM",
   "editedByText": "Edited by nexjsa on 5/7/20 9:53:51 AM",
   "editedByTextShort": "nexjsa on 5/7/20 9:53:51 AM",
   "createdByTextShort": "nexjsa on 5/5/20 10:43:42 AM",
   "ordinal": null,
   "hasPrint": false,
   "dslType": "SCM",
   "locking": -602409739,
   "version": 1,
   "isSeeded": true,
   "editAuthorAlias": "nexjsa",
   "editUserAlias": "nexjsa",
   "editTime": "2020-05-07T13:53:51Z",
   "bind": null,
   "$id": {<flowTemplateName>}.1
}

POST the latest version of a flow template {<flowTemplateName>}: http://localhost:7080/nexj/channel/rest:REST/flowTemplates

The following example shows a request:

Request
{
   "name": {<flowTemplateName>},
   "dslType": "scm",
   "bind": "Person"
}

The following example shows a response:

{
   "data": {
      "$commit-hash": 1896798251,
      "flowCount": 0,
      "summaryStringAuditDates": "Created nexjsa 5/13/20 5:29 PM, Edited nexjsa 5/13/20 5:29 PM",
      "dsl": "",
      "importMode": false,
      "createAuthorAlias": "nexjsa",
      "createTime": "2020-05-13T16:29:23Z",
      "name": {<flowTemplateName>},
      "createUserAlias": "nexjsa",
      "createdByText": "Created by nexjsa on 5/13/20 5:29:23 PM",
      "editedByText": "Edited by nexjsa on 5/13/20 5:29:23 PM",
      "editedByTextShort": "nexjsa on 5/13/20 5:29:23 PM",
      "createdByTextShort": "nexjsa on 5/13/20 5:29:23 PM",
      "ordinal": null,
      "hasPrint": false,
      "dslType": "SCM",
      "locking": 0,
      "version": 2,
      "isSeeded": true,
      "editAuthorAlias": "nexjsa",
      "editUserAlias": "nexjsa",
      "editTime": "2020-05-13T16:29:23Z",
      "bind": "Person",
      "$id": {<flowTemplateName>}.2
   },
   "debug": {
      "unmodified": [],
      "deltas": [
         {
            "operation": "create",
            "metaClass": "bp:FlowTemplate",
            "attributes": [
               {
                  "value": "bp:DSLFileTypeEnum[(oid \"SCM\" \"en\" \"SBPDSLTYPE\")]",
                  "attribute": "dslType"
               },
               {
                  "value": {<flowTemplateName>},
                  "attribute": "name"
               },
               {
                  "value": "Person",
                  "attribute": "bind"
               }
            ]
         }
      ],
      "summary": {
         "createCount": 1,
         "deleteCount": 0,
         "unchangedCount": 0,
         "updateCount": 0,
         "errorCount": 0
      }
   },
   "errors": []
}

PUT the latest version of a flow template {<flowTemplateName>}: http://localhost:7080/nexj/channel/rest:REST/flowTemplates/{<flowTemplateName>}

To use a PUT request, you must first use a GET request to obtain the $commit-hash. The following example shows a response for a GET to the URL to obtain the $commit-hash:

{
   "$commit-hash": 1460810791,
   "flowCount": 0,
   "summaryStringAuditDates": "Created nexjsa 5/13/20 12:29 PM, Edited nexjsa 5/13/20 12:29 PM",
   "dsl": "",
   "importMode": false,
   "createAuthorAlias": "nexjsa",
   "createTime": "2020-05-13T16:29:23Z",
   "name": {<flowTemplateName>},
   "createUserAlias": "nexjsa",
   "createdByText": "Created by nexjsa on 5/13/20 12:29:23 PM",
   "editedByText": "Edited by nexjsa on 5/13/20 12:29:23 PM",
   "editedByTextShort": "nexjsa on 5/13/20 12:29:23 PM",
   "createdByTextShort": "nexjsa on 5/13/20 12:29:23 PM",
   "ordinal": null,
   "hasPrint": false,
   "dslType": "SCM",
   "locking": 0,
   "version": 2,
   "isSeeded": true,
   "editAuthorAlias": "nexjsa",
   "editUserAlias": "nexjsa",
   "editTime": "2020-05-13T16:29:23Z",
   "bind": "Person",
   "$id": {<flowTemplateName>}.2
}

PUT to http://localhost:7080/nexj/channel/rest:REST/flowTemplates/{<flowTemplateName>}to update the "dslType"

After you have obtained the $commit-hash, you can request an update to the dslType:

Request
{
   "$commit-hash": 1460810791,
   "dslType": "NJS"
}

The following example shows a response:

{
   "data": {
      "$commit-hash": 1568761430,
      "flowCount": 0,
      "summaryStringAuditDates": "Created nexjsa 5/13/20 5:29 PM, Edited nexjsa 5/13/20 5:37 PM",
      "dsl": "",
      "importMode": false,
      "createAuthorAlias": "nexjsa",
      "createTime": "2020-05-13T16:29:23Z",
      "name": {<flowTemplateName>},
      "createUserAlias": "nexjsa",
      "createdByText": "Created by nexjsa on 5/13/20 5:29:23 PM",
      "editedByText": "Edited by nexjsa on 5/13/20 5:37:43 PM",
      "editedByTextShort": "nexjsa on 5/13/20 5:37:43 PM",
      "createdByTextShort": "nexjsa on 5/13/20 5:29:23 PM",
      "ordinal": null,
      "hasPrint": false,
      "dslType": "NJS",
      "locking": -848891055,
      "version": 2,
      "isSeeded": true,
      "editAuthorAlias": "nexjsa",
      "editUserAlias": "nexjsa",
      "editTime": "2020-05-13T16:37:43Z",
      "bind": "Person",
      "$id": {<flowTemplateName>}.2
   },
   "debug": {
      "unmodified": [],
      "deltas": [
         {
            "operation": "update",
            "$id": "103478395E802242299329216A71F5322F",
            "metaClass": "bp:FlowTemplate",
            "attributes": [
               {
                  "newValue": "bp:DSLFileTypeEnum[(oid \"NJS\" \"en\" \"SBPDSLTYPE\")]",
                  "oldValue": "bp:DSLFileTypeEnum[(oid \"SCM\" \"en\" \"SBPDSLTYPE\")]",
                  "attribute": "dslType"
               }
            ]
         }
      ],
      "summary": {
         "createCount": 0,
         "deleteCount": 0,
         "unchangedCount": 0,
         "updateCount": 1,
         "errorCount": 0
      }
   },
   "errors": []
}

PUT with an invalid "$commit-hash"

If you pass in a wrong $commit-hash using any PUT request, you will obtain the following response:

Status: 409
{
   "httpMessage": "Conflict",
   "httpCode": 409,
   "moreInformation": "Potential update conflict with bp:FlowTemplate {<flowTemplateName>}. Latest $commit-hash is 1568761430"
}

POST or PUT without the client-timezone header

If you use a POST or PUT request, and do not pass in a client-timezone key in the request header, you will obtain the following response:

Status: 400
{
   "httpCode": 400,
   "httpMessage": "Bad Request"
}

DELETE the latest version of a flow template "templateWithoutAssociatedFlows": http://localhost:7080/nexj/channel/rest:REST/flowTemplates/templateWithoutAssociatedFlows

Status: 200
{
   "details": [
      "Deleted bp:FlowTemplate templateWithoutAssociatedFlows"
   ],
   "message": "Delete success"
}

DELETE the latest version of a flow template "templateWithAssociatedFlows": http://localhost:7080/nexj/channel/rest:REST/flowTemplates/templateWithAssociatedFlows

{
   "type": "nexj.core.persistence.ConstraintViolationException",
   "errors": [
      {
         "statusMessage": "Cannot delete Flow Template \"templateWithAssociatedFlows\" due to existence of associated flows. (err.persistence.cascadeCancel) - (oid #z642A3599DD3A49FB95D40D52420490ED)",
         "statusCode": "err.persistence.cascadeCancel"
      }
   ],
   "httpCode": 500,
   "httpMessage": "Internal Server Error"
}

GET, PUT, or DELETE a non-existed flow template: http://localhost:7080/nexj/channel/rest:REST/flowTemplates/nonexistedTemplate

If you perform a GET, PUT, or DELETE request for a flow template that doesn't exist, you will receive the following response:

Status: 404
{
   "httpMessage": "Not Found",
   "httpCode": 404,
   "moreInformation": "bp:FlowTemplate nonexistedTemplate does not exist"
}

Binding forms with an external schema model and object using REST APIs

NexJ supports binding a form with an external schema model and an external form related object obtained through a REST GET request.

Configuration

To integrate a Process Management form with a new external resource, the following configurations are required:

   Project configuration

  • Create a new channel named rest:{<externalResourceName>} and specify the URL. For example: Channel rest:exampleResource.channel

    Example rest:exampleResource.channel
    <HTTP delete="true" description="Inbound HTTP channel to send REST request" get="true" put="true" url="https://master.atmos.nexj.exampleResource/api/rest/"/>
  • Create a new meta file named rest:{<externalResourceName>}:SchemaModel (for example, rest:exampleResource:SchemaModel). This file should apply the bp:rest:SCHEMA_MODEL aspect and override the following events:

    • getRelatedObjectPayload event for generating a request payload for getting an external related object used by a flow
    • getSchemaRequestPayload event for generating a request payload for getting the schema model
    • getSyncRequestPayload event for generating a request payload for syncing an update to external objects
    • getExternalEnum event for getting the options of an external enumeration
    • getExternalObject event for generating a request payload for getting an external object
    • getExternalObjects event for getting a list of external objects when a bind schema name is given, pagination and ordering should be implemented in it
  • Create a new meta file named rest:{<externalResourceName>}:ExternalObject. This file should set bp:rest:ExternalObject as the base class, and specify a list of associated fields used in objects, as well as all the fields exposed for object type fields over API, as attributes of this meta class. For example, specify a caption to represent a field caption exposed for object type fields, or specify an entity to represent the associated field entity exposed for object field entities.

   Form configuration

  • Specify the bind of the form in the following format:  REST.{<externalResourceName>}.{<schemaName>}
    For example: REST.exampleResource.Person
  • Specify the options property for combo and radio controls if an external definition is used. For more information, see Using an external enumeration.
  • Specify properties for an object or objects control if you bind the control with external objects. For more information, see Using external objects.

Mock schema model

The following example shows the definition for the sample REST schema model called personSchema.

(message
   (: properties
      (message
         (: name (message (: title "Last Name") (: type "string") (: maxLength 256)))
         (: firstName (message (: title "First Name") (: type "string") (: maxLength 256)))
         (: gender
            (message
               (: enum (collection "FEMALE" "MALE" "UNKNOWN"))
               (: title "Gender")
               (: type "string")
               (: bounded #t)
            )
         )
         (: maritalStatus
            (message
               (: enum (collection "COMMON_LAW" "DIVORCED" "MARRIED" "SINGLE" "WIDOWED"))
               (: title "Marital Status")
               (: type "string")
            )
         )
         (: birthCountry
            (message
               (: enum (collection "CANADA" "UNITED_STATES_OF_AMERICA" "OTHER"))
               (: title "Country")
               (: type "string")
               (: readOnly #t)
            )
         )
         (: residenceCountry
            (message
               (: enum (collection "CANADA" "UNITED_STATES_OF_AMERICA" "OTHER"))
               (: title "Country of Residence")
               (: type "string")
            )
         )
         (: primaryLanguage
            (message
               (: enum (collection "ARABIC" "MANDARIN" "GERMAN" "ENGLISH" "FRENCH" "PORTUGUESE" "RUSSIAN" "SPANISH" "CANTONESE"))
               (: title "Primary Language")
               (: type "string")
            )
         )
         (: birthDate (message (: format "date") (: title "Birth Date") (: type "string")))
         (: isDoNotCall
            (message
               (: title "Do Not Call")
               (: type "boolean")
               (: example "true")
            )
         )
         (: owner
            (message
               (: properties
                  (message
                     (: ui_caption (message (: readOnly #t) (: title "Name") (: type "string") (: example "Tim Lamont")))
                     (: $id (message (: format "oid") (: title "NexJ OID") (: type "string") (: example "C20000000000000001")))
                  )
               )
               (: title "Owner")
               (: type "object")
            )
         )
         (: parties
            (message
               (: items
                  (message
                     (: properties
                        (message
                           (: party 
                              (message 
                                 (: ui_caption (message (: readOnly #t) (: title "Subtype") (: type "string") (: example "Tim Lamont")))
                                 (: $id (message (: format "oid") (: title "NexJ OID") (: type "string") (: example "C20000000000000001")))
                              )
                           )
                           (: ui_caption (message (: readOnly #t) (: title "Subtype") (: type "string") (: example "Tim Lamont")))
                           (: $id (message (: format "oid") (: title "NexJ OID") (: type "string") (: example "C20000000000000001")))
                        )
                     )
                     (: type "object")
                     (: required (collection "party"))
                  )
               )
               (: title "Related Parties")
               (: type "array")
            )
         )
         (: identifications
            (message
               (: items
                  (message
                     (: properties
                        (message
                           (: ui_caption (message (: readOnly #t) (: title "Subtype") (: type "string") (: example "Tim Lamont")))
                           (: $id (message (: format "oid") (: title "NexJ OID") (: type "string") (: example "C20000000000000001")))
                        )
                     )
                     (: type "object")
                  )
               )
               (: title "Identifications")
               (: type "array")
            )
         )
         (: telcoms
            (message
               (: items
                  (message
                     (: properties
                        (message
                           (: address (message (: title "Phone/Email") (: type "string") (: maxLength 256)))
                           (: typeName (message (: title "Subtype") (: type "string") (: maxLength 256)))
                           (: template (message (: enum (collection "EMAIL" "PHONE")) (: title "Template") (: type "string")))
                           (: ui_caption (message (: readOnly #t) (: title "Subtype") (: type "string") (: example "Tim Lamont")))
                           (: $id (message (: format "oid") (: title "NexJ OID") (: type "string") (: example "C20000000000000001")))
                        )
                     )
                     (: type "object")
                     (: required (collection "template" "typeName" "address"))
                  )
               )
               (: title "Communication")
               (: type "array")
            )
         )
      )
   )
   (: $id (message (: format "oid") (: title "NexJ OID") (: type "string") (: example "C20000000000000001")))
   (: type "object")
   (: required (collection "name" "firstName"))
)

personSchema has the following attributes:

Attribute nameTitleTypeOptionsOther properties
nameLast NamestringNot applicablemaximum length: 256 characters
firstNameFirst NameStringNot applicablemaximum length: 256 characters
genderGenderEnumerationDefault options: "FEMALE," "MALE," and "UNKNOWN"bounded: true
maritalStatusMarital StatusEnumeration

Default options: "COMMON_LAW" "DIVORCED" "MARRIED" "SINGLE" "WIDOWED"

Not applicable
birthCountryCountryEnumeration

Default options: "CANADA," "UNITED_STATES_OF_AMERICA," and "OTHER"

External mock options are shown in the Mock external enumeration section.

read only: true
residenceCountryCountry of ResidenceEnumeration

Default options: "CANADA," "UNITED_STATES_OF_AMERICA," and "OTHER"

External mock options are shown in the Mock external enumeration section.

Not applicable
primaryLanguagePrimary LanguageEnumeration

Default options: "ARABIC" "MANDARIN" "GERMAN" "ENGLISH" "FRENCH" "PORTUGUESE" "RUSSIAN" "SPANISH" "CANTONESE"

External mock options are shown in the Mock external enumeration section.

Not applicable
birthDateBirth DatestringNot applicableformat: date
isDoNotCallDo Not CallbooleanNot applicableNot applicable
owner

Owner

object

Shown in the Mock external objects section.
Object attributes: ui_caption, $id
partiesRelated PartiesarrayShown in the Mock external objects section.

Object attributes: ui_caption, $id

Associated object party attributes: ui_caption, $id

identificationsIdentificationsarrayShown in the Mock external objects section.
Object attributes: ui_caption, $id
telcomsCommunicationarrayNot applicablerequired attributes: template, typeName, address

The required properties under each object indicate all the required attributes for it, and which values should not be null when the form is being submitted. Null values will generate an error message.

Using an external enumeration

To bind a combo or radio control with an external enumeration, specify (: options "REST.{<externalResourceName>}.{<schemaName>}.enum.<{enumerationName}>") in the definition. Combo or radio controls that bind with an external enumeration display their external options when you specify the options property and an external definition exists. Otherwise, they show the default options provided in the schema model definition. For example:

Bind a combo or radio control with an external enumeration
; Configure combo gender to use external enumeration named "gender"
(bp:combo gender (: options "REST.mock.Contact.enum.gender"))

; Configure combo template to use external enumeration named "template"
; "template" is an associated field of "telcoms", so option property is configured to "REST.mock.Contact.enum.telcoms.template"
(bp:combo template (: options "REST.mock.Contact.enum.telcoms.template"))

; Configure radio maritalStatus to use external enumeration named "maritalStatus"
; no external definition of "maritalStatus" is provided, thus this radio uses default options provided in mock schema model
(bp:radio maritalStatus (: options "REST.mock.Contact.enum.maritalStatus"))

; radio birthCountry uses default options provided in mock schema model as option property is not configured
(bp:radio birthCountry)

Mock external enumeration

The mock external enumeration in the following example is used for combo and radio controls. 

For example, if you bind a combo control with a gender enumeration, it displays the following mock external options: "Male," "Female," and "Unknown."

; Definition of external enumeration named "gender"
(message
   (: options
      (collection
         (message (: sortOrder 0) (: active #t) (: name "MALE") (: ui_caption "Male"))
         (message (: sortOrder 1) (: active #t) (: name "FEMALE") (: ui_caption "Female"))
         (message (: sortOrder 2) (: active #t) (: name "UNKNOWN") (: ui_caption "Unknown"))
      )
   )
)

; Definition of external enumeration named "template"
(message
   (: options
      (collection
         (message
            (: sortOrder 0)
            (: active #t)
            (: name "EMAIL")
            (: ui_caption "Email Address")
         )
         (message
            (: sortOrder 1)
             (: active #t)
             (: name "PHONE")
             (: ui_caption "Phone Number")
          )
       )
    )
)

Using external objects

When you bind Process Management forms with the external REST schema model objects, some properties are optional. This is different from when you bind forms with the NexJ model objects where these same properties are required.

Object(s) properties:

  • valueCaption
    It is a required property.
  • assoc
    It is a required property when a multipicker control requires assoc to be specified.
  • valueType
    It is a non-required property. It is calculated to be in the format of "REST.<{externalProjectName}>.<{schemaName}>.object.<{bindName}>". For example:
    REST.exampleResource.Person.object.entities
  • assocType
    It is a non-required property. It is calculated to be in the format of "REST.<{externalProjectName}>.<{schemaName}>.object.<{bindName}>.<{assocName}>". For example:
    REST.exampleResource.Person.object.entities.entity
  • filterPath
    It is an optional property. Custom filtering can be implemented in getExternalObjects, as mentioned in Project configuration.
  • order
    It is an optional property. Custom ordering can be implemented in getExternalObjects, as mentioned in Project configuration.
  • initialize
    It is an optional property for the create instance case. Its value format is one of the following:
    • object:  (: initialize (message (: id <{string_id}>) (: type "REST.<{externalProjectName}>.<{schemaName}>")))
    • objects: (: initialize (collection(message (: id <{string_id}>) (: type "REST.<{externalProjectName}>.<{schemaName}>"))))

The following example shows how to use object, objects with external objects, the valueType, and assocType values.

; valueType of owner M1 picker is calculated to "REST.mock.Contact.object.owner"
(bp:object owner (: valueCaption "ui_caption"))

; owner default to object which id is "C20000000000000035" in create new contact case
(bp:object
   owner
   (: valueCaption "ui_caption")
   (: initialize (message (: id "C20000000000000035") (: type "REST.mock.Owner")))
)

; valueType of parties MM picker is "REST.mock.Contact.object.identifications"
(bp:objects identifications (: valueCaption "ui_caption"))

; identifications default to identification which id is "C20000000000000101" and "C20000000000000102" in creating new contact
(bp:objects
   identifications
   (: valueCaption "ui_caption")
   (: initialize
      (collection
         (message (: id "C20000000000000101") (: type "REST.mock.Identification"))
         (message (: id "C20000000000000102") (: type "REST.mock.Identification"))
      )
   )
)

; valueType of parties MM picker is "array", assocType is calculated to "REST.mock.Contact.object.parties.party"
(bp:objects parties (: assoc "party") (: valueCaption "ui_caption"))

; parties default to party which id is "C200000000000000013" and "C200000000000000014" in creating new contact
(bp:objects
   parties
   (: assoc "party")
   (: valueCaption "ui_caption")
   (: initialize
      (collection
         (message (: id "C200000000000000013") (: type "REST.mock.Party"))
         (message (: id "C200000000000000014") (: type "REST.mock.Party"))
      )
   )
)

Mock external objects

Mock external objects are used as items that display in M1 and MM pickers. For example, if you are using a M1 picker that has an objectType that is calculated to REST.mock.Contact.object.owner, when a user clicks the Select  button on the picker control, the options shown in the following code example for owner are displayed in the picker. A user can then select any of the options inside the picker in order to specify the value for owner.

; Definition of external object "owner"
(message
   (: options
      (collection
         (message (: $id "C20000000000000035") (: ui_caption "HC542432") (: sortOrder 0))
         (message (: $id "C20000000000000036") (: ui_caption "HC542433") (: sortOrder 1))
         (message (: $id "C20000000000000037") (: ui_caption "HC542434") (: sortOrder 2))
         (message (: $id "C20000000000000038") (: ui_caption "HC542435") (: sortOrder 3))
         (message (: $id "C20000000000000039") (: ui_caption "HC542436") (: sortOrder 4))
         (message (: $id "C20000000000000040") (: ui_caption "HC542437") (: sortOrder 5))
      )
   )
)

; Definition of external object "parties"
(message
   (: options
      (collection
         (message
            (: $id "C20000000000000007")
            (: ui_caption "Parties1")
            (: sortOrder 0)
            (: party (message (: $id "C200000000000000013") (: ui_caption "Party1") (: sortOrder 0)))
         )
         (message
            (: $id "C20000000000000008")
            (: ui_caption "Parties2")
            (: sortOrder 1)
            (: party (message (: $id "C200000000000000014") (: ui_caption "Party2") (: sortOrder 1)))
         )
         (message
            (: $id "C20000000000000009")
            (: ui_caption "Parties3")
            (: sortOrder 2)
            (: party (message (: $id "C200000000000000015") (: ui_caption "Party3") (: sortOrder 2)))
         )
         (message
            (: $id "C20000000000000010")
            (: ui_caption "Parties4")
            (: sortOrder 3)
            (: party (message (: $id "C200000000000000016") (: ui_caption "Party4") (: sortOrder 3)))
         )
         (message
            (: $id "C20000000000000011")
            (: ui_caption "Parties5")
            (: sortOrder 4)
            (: party (message (: $id "C200000000000000017") (: ui_caption "Party5") (: sortOrder 4)))
         )
         (message
            (: $id "C20000000000000012")
            (: ui_caption "Parties6")
            (: sortOrder 5)
            (: party (message (: $id "C200000000000000018") (: ui_caption "Party6") (: sortOrder 5)))
         )
      )
   )
)

Mock related object

The following example shows the properties of the sample external contact called "Tim Lamont":

(message
   (: name "Lamont")
   (: firstName "Tim")
   (: gender "MALE")
   (: primaryLanguage "ENGLISH")
   (: maritalStatus "MARRIED")
   (: birthDate "1954-07-08")
   (: birthCountry "UNITED_STATES_OF_AMERICA")
   (: residenceCountry "UNITED_STATES_OF_AMERICA")
   (: isDoNotCall #f)
   (: $id "C2000000000000000D")
   (: owner
      (message
         (: links
            (message
               (: avarar (message (: href "/assets/attachments/attachment?class=crm:user:Image&type=mimeType&data=mimeData&oid=1")))
               (: self (message (: href "/api/rest/entitlements/C20000000000000035")))
            )
         )
         (: ui_caption "HC542433")
         (: $id "C20000000000000036")
      )
   )
   (: parties
      (collection
         (message
            (: $id "C20000000000000007")
            (: ui_caption "Parties1")
            (: sortOrder 0)
            (: party (message (: $id "C200000000000000013") (: ui_caption "Party1") (: sortOrder 0)))
         )
         (message
            (: $id "C20000000000000008")
            (: ui_caption "Parties2")
            (: sortOrder 1)
            (: party (message (: $id "C200000000000000014") (: ui_caption "Party2") (: sortOrder 0)))
         )
         (message
            (: $id "C20000000000000009")
            (: ui_caption "Parties3")
            (: sortOrder 2)
            (: party (message (: $id "C200000000000000015") (: ui_caption "Party3") (: sortOrder 0)))
         )
         (message
            (: $id "C20000000000000010")
            (: ui_caption "Parties4")
            (: sortOrder 3)
            (: party (message (: $id "C200000000000000016") (: ui_caption "Party4") (: sortOrder 0)))
         )
      )
   )
   (: identifications
      (collection
         (message (: $id "C20000000000000101") (: ui_caption "ID") (: sortOrder 0))
         (message (: $id "C20000000000000103") (: ui_caption "Driver License") (: sortOrder 1))
      )
   )
   (: telcoms
      (collection
         (message
            (: address "lamont.tim@gmail.com")
            (: typeName "Personal Email")
            (: template "EMAIL")
            (: ui_caption "Personal Email")
            (: $id "C2000000000000000E")
         )
         (message
            (: address "tlamont@allencompany.com")
            (: typeName "Work Email")
            (: template "EMAIL")
            (: ui_caption "Work Email")
            (: $id "C2000000000000000F")
         )
         (message
            (: address "416-555-2345")
            (: typeName "Home")
            (: template "PHONE")
            (: ui_caption "Home")
            (: $id "C20000000000000010")
         )
         (message
            (: address "416-555-1149")
            (: typeName "Mobile")
            (: template "PHONE")
            (: ui_caption "Mobile")
            (: $id "C20000000000000011")
         )
         (message
            (: address "416-554-5559")
            (: typeName "Business")
            (: template "PHONE")
            (: ui_caption "Business")
            (: $id "C20000000000000012")
         )
      )
   )
)

Sample form using the mock schema model

This section provides examples that show how to edit an existing instance and create a new instance.

Example: Editing an existing instance

The following example shows how to bind a form using personSchema and "Tim Lamont":

(define definition
	(bp:flow
      (bp:page
         profilePage
         (: caption "Profile")
         (bp:section
            schemaSection
            (bp:text name)
            (bp:text firstName)
            (bp:combo gender (: options "REST.mock.Contact.enum.gender"))
            (bp:radio maritalStatus)
            (bp:radio residenceCountry (: options "REST.mock.Contact.enum.residenceCountry"))
            (bp:radio birthCountry (: options "REST.mock.Contact.enum.birthCountry"))
            (bp:combo primaryLanguage)
            (bp:checkbox isDoNotCall)
            (bp:object owner (: valueCaption "ui_caption"))
            (bp:objects parties (: assoc "party") (: valueCaption "ui_caption"))
            (bp:objects identifications (: valueCaption "ui_caption"))
         )
      )
      (bp:page
         owner
         (bp:section ownerSection
            (bp:text ui_caption)
         )
      )
      (bp:page
         telcoms
         (bp:section telcomSection
            (bp:combo template (: options "REST.mock.Contact.enum.telcoms.template"))
            (bp:text address)
            (bp:text typeName)
         )
      )
      (: bind "REST.mock.Contact")
   )
)

(define flow (bp:Flow'createFlow (bp:FlowTemplate'createTemplate "schemabind" definition) (: objectId "C2000000000000000D") (: idFormat '$id)))

(commit)

The value of the objectId property should be the ID of the external object, and the value of the idFormat property should be the key of the ID for the external object. By default, idFormat is set to '$id.

NexJ provides a sample mock model, which has the same definition as personSchema and sample object "Tim Lamont." When you bind the above form to REST.mock.Contact, the mock model is used.

A form template called "testschemabind," which is similar to the form shown in the "Binding a form using personSchema and Tim Lamont" example, is also provided in Process Management.

Example: Creating a new instance

When you are creating the flow to use an integrated form to create a new instance, you do not need to pass in an objectId. This is similar to using the forms bind with NexJ model objects.

Using an integrated form to create a new instance
(define flow (bp:Flow'createFlow (bp:FlowTemplate'createTemplate "newInstance" definition) (: idFormat '$id)))

(commit)

The mock model does not support creating a new contact.

Form submission

After a user make changes in a form and clicks Submit, Process Management automatically generates the required REST PUT, POST, and DELETE requests, and sends these requests to external services to save the changes to the external objects.

Any changes to a form that uses schema mock data will not be saved by clicking Submit.

Conflicts

Conflicts are shown when an external object has been updated but the Process Management form still contains its old values. When creating a form, a proper idFormat needs to be passed in, as shown in the sample code above. Otherwise, improper conflicts are shown for collection items, which is caused by a failure to read items based on their ID.

Related link

Enabling and configuring REST API v2