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 examplelocalhost: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 likeBPCUSTOMER
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 likeBPCUSTOMER
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 firstN
results.key=condition
: only returns the keys that satisfy the condition. For examplekey=gt.0143
will return the customers with a key greater than0143
. This parameter is typically used in conjucttion withcount
to page through large result sets (see the paging section below).where=predicate
: filters the result. Only the resources that satisfypredicate
will be returned. For example,where=left(BPCNAM,4) eq 'Test'
will return the customers whose name starts withTest
.orderBy=criteria
: controls how the result will be sorted. The criteria is a comma-separated list of property names followed by an optionsasc
ordesc
keyword. For exampleorderBy=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.
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.