One moment please...
Untitled Document

Exact Globe

CRUD actions using the REST Entity service

 

The REST Entity service is an oData adapter built on top of the SOAP based Entity service. This means that the transfer protocols follow the oData conventions, while the business logic is similar to the SOAP service. The REST Entity service supports both ATOM XML and JSON payload formatting.

Examples will be given using the entity Account, which is used to maintain associates of diferent types (customers, suppliers, resellers) as well as track prospective customers in the various stages of a sales cycle(suspect,->lead->prospect->customer). This document will focus primarily on the markup of the request and response payloads, as well as the structure of the request URI. Specialized procedures like dealing with binary components of an entity (pictures, file attachments and large texts), as well as dealing with header/line data (sales orders, invoices, financial entries) will be outlined in separate documents that focus more on the process.

Request markup

With all requests, the following considerations for its markup are important.

·         Credentials: The Entity service itself runs under a service account without authorization to any feature in Globe, and will impersonate towards the credentials provided. These credentials should be provided as NTLM network credentials and authenticate the client as a user that exists in Globe as an active employee with sufficient function rights to maintain the data that the client tries to maintain.

·         ContentType:  application/atom+xml if the request payload is formatted using ATOM markup. application/json if the request payload is formatted using JSON markup. Not relevant for Retrieve and Delete actions, since those do not require a content payload.

·         Accept: application/atom+xml,application/xml; charset=utf-8 if the response payload should be formatted using ATOM markup. application/json,text/javascript; charset=utf-8 if the response payload should be formatted using JSON markup. Not relevant for Update and Delete actions, which don’t return a content payload.

·         Method: POST for Create, GET for Retrieve/query, MERGE for Update and DELETE for Delete.

On top of this standard markup, two custom fields, which point to the database to be used, should be included in the request header:

·         ServerName: needs to contain the network address of the SQL server instance on which the database is located. This address should be relative to the machine that hosts the Entity service.

·         DatabaseName: the name of the database under which it is stored in SQL server. This should be the name in SQL itself. Not the company number that is usually shown in Globe itself.


 

URI conventions

Within oData, there is an URI that points to the entity as a whole, and one that points to a specific record within that entity. This record specific URI includes the primary key for that entity, and is used to retrieve the fields for that specific record, as well as to perform Update and Delete actions. This URI is included in the response payload of Create and Retrieve actions. The precise location depends on whether ATOM or JSON markup is used.

The URI starts with the network address of the service host, relative to the calling client application, followed by the portnumber under which the REST service is running. This portnumber is stored in the file Exact.WindowsService.config in the XMD folder of the Globe installation on the service host, and is usually 8020.

The service location is /Services/Exact.Entity.REST.EG. The full URI for the Account entity when calling the service locally would be:

http://localhost:8020/Services/Exact.Entity.REST.EG/Account

The URI to access a specific account within this entity will be structured as follows (using customer 60089 in a McBean demo company):

http://localhost:8020/services/Exact.Entity.REST.EG/Account(guid'e11c4af3-7fa9-4a61-9152-4a8b7743f911')

When retrieving data, a query expression can be supplied through a set of parameters to both filter results and provide input that affects the behavior of the retrieve action. This uses the following URI parameters:

·         $top: limits the number of records returned in a single response. If more records are to be returned, the subsequent records can be retrieved by using a link in the response payload that is marked as next (ATOM) or __next (JSON). If this parameter is missing, as many records will be returned as what fits within the maximum allowed chunk size for the service, or all records found, whichever is less.

·         $select: causes the service to only return those properties that are mentioned by this parameter. If this parameter is missing, all properties will be returned.

·         $orderby: determines the properties by which the results are sorted within the response. If this parameter is missing, the sorting method is however SQL returned the results to the service.

·         $filter: This parameter is used twofold. It can be used to filter for only specific property values, but it is also used to provide input to the service if this is needed (this is, for example used to perform a retrieve that should include binary data, which by default is omitted). If this parameter is missing, all records stored within this entity will be recovered.


 

The $filter expression supports the following operands:

·         eq: equal to

·         ne: not equal to

·         gt: greater than

·         ge: greater than or equal to

·         lt: lesser than

·         le: lesser than or equal to

This example retrieves the identity GUID for account code 60089 (note that with right aligned fields leading spaces should be included):

http://localhost:8020/Services/Exact.Entity.REST.EG/Account/?$top=1&$select=ID&$filter=AccountCode eq '               60089'


 

Entity payload

The Entity service uses a fragment of the entity payload, as defined by the oData conventions for both up and download. This format revolves around a collection of name-value pairs which list all relevant properties and their values. In response payloads, either all properties, or all properties specified by the $select URI parameter are included. In request payloads, only those properties that are relevant should be included. For Create actions this means all properties that are either mandatory or for which a non default value should be used. For Update actions this means all properties for which the value should be changed.

ATOM XML markup

The entity markup in the ATOM format is largely the same for request and response. This is because it includes a lot of mandatory overhead that while not actively used, is still required by the oData serializer of the service. The format is as follows:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>

<entry xmlns="http://www.w3.org/2005/Atom"

        xmlns:m="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"

        xmlns:d="http://schemas.microsoft.com/ado/2007/08/dataservices">

            <title/>

            <summary/>

            <updated>2015-06-11T08:15:57Z</updated>

            <author>

                <name/>

            </author>

            <category scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" term=Exact.Metadata.Entity.Account

            <content type="application/xml">

                <m:properties>

                    <d:ID>e11c4af3-7fa9-4a61-9152-4a8b7743f911</d:ID>

                    .

                    .

                </m:properties>

            </content>

        </entry>

 

Within a query result, multiple <entry> nodes will be included within a <feed> node that encapsulates them all. There will also be a <link rel=’next’> node that contains the link to retrieve the next batch of results if not all results could be returned in a single response. The date in the <updated> node should be in the XML format for UTC date time notation. The term attribute for the <category> node should be Exact.Metadata.Entity.EntityName, with EntityName the name of the entity used.


 

JSON markup

The payload format for JSON is a lot more compact, but this makes the differences between the request and response markup, as well as the response markup for single and multiple records a bit more pronounced. The request markup is simply a name-value pair collection for every relevant property:

{

   “AccountName”:”Restaurant Enkhuizen”,

   “CurrencyCode”:”EUR”,

   .

   .

}

 

The name should be the property name as exposed by that entity’s metadata. The value should be in the type appropriate for that property, which is also described by the entity’s metadata.

 

The single record response markup is as follows:

{

   “d”:{

      “__metadata”:{

         "id":"http://localhost:8020/services/Exact.Entity.REST.EG/Account(guid'e11c4af3-7fa9-4a61-9152-4a8b7743f911')",

         "uri":"http://localhost:8020/services/Exact.Entity.REST.EG/Account(guid'e11c4af3-7fa9-4a61-9152-4a8b7743f911')",

         "type":"Exact.Metadata.Entity.Account"

      },

      “AccountName”:”Restaurant Enkhuizen”,

      “CurrencyCode”:”EUR”,

      .

      .

   }

}

 

The name-value pair collection is in this situation embedded in a collection named “d”, which also contains a metadata element labeled “__metadata”. In this element, the most relevant element is “id”, which contains the URI pointing to the record concerned.


 

The multiple record markup is as follows:

{

   “d”:{

      “results”:[

         {

            “__metadata”:{

               …

            },

            “AccountName”:”Restaurant Enkhuizen”,

            .

            .

        },

        {

            “__metadata”:{

               …

            },

            …

         },

         .

         .

      ],

      “__next”:” http://localhost:8020/Services/Exact.Entity.REST.EG/Account/?$filter=ID%20eq%20guid'e11c4af3-7fa9-4a61-9152-4a8b7743f911'%20and%20IsBinaryServiceEnabled%20eq%20true&$top=1&$skiptoken=126L”

   }

}

 

In this situation, the property collection, along with the metadata element are put in an array with one element per record. This array is put in a collection labelled “results”, which also contains the element containing the URI to retrieve the next batch of records. The results collection is put in the d collection.


 

CRUD action exchanges

 

Create

The request needs to be a POST to the entity generic URI. The request payload needs to contain all properties that are either mandatory, or for which you do not desire the value to be generated by the business logic. The response payload will contain the entity as it has been stored, along with the record specific URI for it.

Retrieve

The request needs to be a GET. It can either be done to the record specific URI of a single record, or the generic URI if you wish to perform a search or need to provide query criteria. All input to the service is provided by the URI. There is no request payload. The response payload will contain the data stored in the requested record (record specific URI), or a set of property collections that match the provided criteria, one collection per record (query on the entity generic URI).

Update

The request needs to be a MERGE on the record specific URI of the record that you wish to update. The request payload needs to contain all properties that you wish to change. There is no response payload. If you wish to examine the data after updating it, you will need to follow up your Update with a Retrieve.

Delete

The request needs to be a DELETE on the record specific URI of the record that you wish to delete. This is all the information that will be exchanged. There is neither a request nor a response payload. If you get an OK or No content response, the Delete was successful.

 

 

Document Number: 26.579.581

Disclaimer
Despite the continued efforts of Exact to ensure that the information in this document is as complete and up-to-date as possible, Exact can not be held accountable for the correctness and/or completeness and/or specific applicability of the published and/or requested information in this document. Exact shall not be liable for any direct, indirect, incidental, special or consequential damages, lost profits or for business interruption arising out of the use of this document. The extraction and use of information from this document remains at all times completely within the user's own risk.