SData web service for Query

This article describes how to query a list of resources with a Web Service query.

Query URL

You can query a list of resources by sending an HTTP GET request to the following URL:

http://myserver:myport/api1/x3/erp/MYENDPOINT/MYCLASS?representation=MYREPR.$query

where:
  • myserver:myport is your server name and port number. For example localhost:8124 if the SAFE X3 web server is installed locally.
  • MYENDPOINT is the name of your Sage X3 endpoint.
  • MYCLASS is the name of the class that you want to query. It may be a standard class like BPCUSTOMER or a custom class that you have implemented (see the class dictionaries documentation).
  • MYREPR is the name of the representation that you want to query. It may be a standard representation like BPCUSTOMER or a custom one (see the representation dictionaries documentation).

Note MYREPR must be a representation for MYCLASS. Otherwise you will get an error. A future version of the Web API will allow you to pass only MYREPR but this version (api1) requires both parameters.

As is, this query returns the first 20 results but you can alter this behavior by passing additional parameters:

  • count=N: changes the page size. The query will return the first N results.
  • key=condition: only returns the keys that satisfy the condition. For example key=gt.0143 will return the customers with a key greater than 0143. This parameter is typically used in conjucttion with count to page through large result sets (see the paging section below).
  • where=predicate: filters the result. Only the resources that satisfy predicate will be returned. For example, where=left(BPCNAM,4) eq 'Test' will return the customers whose name starts with Test.
  • orderBy=criteria: controls how the result will be sorted. The criteria is a comma-separated list of property names followed by an options asc or desc keyword. For example orderBy=BPCNAM desc, BPCNUM asc. Only the properties present on the query facet (whenever they are visible or invisible) can be chosen to sort data.

Status code

If the query is correctly defined (ie. the class, representation, syntax is ok), the request will return an HTTP status of 200.

Otherwise it will return an HTTP error status (4xx or 5xx).

JSON feed

A Web API query returns a JSON feed structured as follows:

CODECODE CODE javascript
{
    "$itemsPerPage": 20,
    "$resources": [
        { "BPCNUM": "0113", "BPCNAM": "ACME Inc.", ... },
        { "BPCNUM": "0120", "BPCNAM": "ACME Ltd.", ... },
        ... 18 more results (at most)
    ],
    "$links": {
        "$next": {
            "$url": "http://myhost:8124/api1/x3/erp/MYENDPOINT/BPCUSTOMER?representation=BPCUSTOMER.$query&key=gt.0197",
            "$type": "application/json",
            "$method": "GET"
        },
        "$last": {
            "$url": "http://myhost:8124/api1/x3/erp/MYENDPOINT/BPCUSTOMER?representation=BPCUSTOMER.$query&key=lt",
              "$type": "application/json",
              "$method": "GET"
          }
    }
}

The list of resources is not returned directly. Instead, it is embedded into a small envelope. You access it as the $resources value of the envelope.

The $itemsPerPage value is the number of resources that the server returns in each page. It is not necessarily what you requested with the count parameter (because the server may cap your value to limit memory allocation). It is the number or records returned in $resources, except at the end of the feed where $resources will usually have less elements than the page size.

The $links object gives you links that you can use to interact further with the service. In a query feed, the server will return paging links ($first, $last, $prev and $next), which are handy for paging but it may also return representation-specific links.

Paging

The paging links are included in the feed to make it easy for your program to page through the results. Your program doesn't need to build the URL to get the next page, it can directly use the $url which is returned in the $next link. Also, the $next link will be absent on the last page of a feed, which is handy to detect the end of a feed.

For example, the following code can be used to read all the pages of a query feed:
CODECODE CODE javascript
var baseUrl = "http://" + config.host + "/api1/x3/erp/" + config.endpoint;
// Returns one page of the feed
function getCustomersPage(_, url) {
    var response = ez.devices.http.client({
        url: url,
        method: "GET",
        headers: {
            authorization: basicToken(config.login, config.password),
        },
    }).end().response(_);
    if (response.statusCode !== 200) throw new Error("request failed with status " + response.statusCode);
    return JSON.parse(response.readAll(_));
}
// Iterates through all the feed's pages
function readAllCustomers(_) {
    var url = baseUrl + "/BPCUSTOMER?representation=BPCUSTOMER.$query?count=20";
    var pageNum = 0; // for our page banner
    while (true) {
        var page = getCustomersPage(_, url);
        console.log("**** PAGE " + ++pageNum + " ****"); // small banner 
        page.$resources.forEach(function(res) {
            console.log(res.BPCNUM + ":\t" + res.BPCNAM);
        });
        if (!page.$links.$next) break;
        // loop with the URL of the $next link
        url = page.$links.$next.$url;
    }
    console.log("**** DONE - feed has " + pageNum + " pages ****");
}
// don't forget to call readAllCustomers, otherwise nothing happens.
readAllCustomers(_);

Testing interactively

As described in the overview, you can test Web API queries directly in the browser, or in a tool like Postman.