Kourier Integrator Online Help
With Kourier you can create a resource-oriented Application Programming Interface (API), based upon the REST open standard architecture which allows you to retrieve and update information in your U2-based application in real-time.
The following characteristics apply to all Kourier REST resources:
Developers create a REST API for their application by creating one or more REST Resource Specifications that define the resources available within the integration and how those resources are implemented as either a REST Export Specification (Outbound) or a REST Import Specification (Inbound).
This topic describes the general capabilities and features when Kourier is used as a REST server. Kourier can also be used to build a REST based client.
An outbound REST resource is implemented as a Kourier Export Specification. A REST Export Specification allows you to define specific parameters for the resource, reference those parameters in the SELECT statement used to retrieve information from the U2 database or while creating the response for the resource. Parameters can be passed in the URL as query string or in a request header field.
Here is an example GET URL: http://<base-url>/RWS/CUSTOMER/SEARCH?NAME=A]&CITY=SAN
Any query parameter in the URL can be accessed using a Kourier substitution string. For example, if you have a parameter called “NAME” you can access that parameter using the string {%NAME} in a SELECT statement.
If you need to access a query parameter from UniBASIC code, you can do that with the following code fragment:
QUERYHDRS = PROPS$<KEX$QUERYHDRS
CALL KMK.GETHDR(QUERYHDRS, 'NAME', L4.NAME)
If you need to access a parameter in a request header field from UniBASIC code, you can do that with the following code fragment:
IHTTPHDRS = PROPS$<KEX$IHTTPHDRS
CALL KMK.GETHDR(IHTTPHDRS, 'X-Application-User', USERID)
When creating a GET type resource/sub-resource, Kourier has several built-in capabilities that add to the utility and usability of the REST resource. These capabilities include:
Kourier allows the API designer to create any number of parameters when creating a GET request. These parameters can either be in the query string or in the request header fields. Each parameter can specify a minimum/maximum length, if the parameter is required, and any edits such as dates, enumerations, or data lookups for which the value of the query parameter must conform.
The API consumer can include wildcard characters in query parameters to facilitate searching for partial matches in the data. Use the “[“ character for an ending with search, the “]” character for a beginning with search and the “[]” characters for a containing with search.
Kourier leverages the native SELECT capabilities in U2 to support robust selection criteria when creating GET requests. You can define the SELECT statement with placeholders which are resolved dynamically at run-time based upon the value of a query parameter included in the URL. To support complex selection criteria, you can programmatically build the SELECT statement at run-time using the Before Select event handler.
The API consumer may not always need the full representation of a resource. Kourier allows the API consumer to select which fields are returned in a GET request by specifying the “Fields” query parameter. This parameter accepts a comma delimited list of field names. By doing this, the API consumer can minimize network traffic and speed up their own usage of the API.
Kourier allows the API consumer to sort the items returned in a request by specifying the “SortBy” query parameter. This parameter accepts a comma delimited list of field names to accommodate complex sorting requirements. A descending sort by can be specified by preceding the field name with a minus (-) character.
In many cases, a GET request may return a large number of records in the response. Kourier automatically limits the number of records returned to either the system default value (usually 100) or the value configured in the GET request using the EXPORT-MAX-ITEMS keyword. The API consumer can “walk” the result set by using the “Page” and “PerPage” query parameters along with the information returned in the X-Count-Items response header field.
An inbound REST resource is implemented as a Kourier Import Specification. A Kourier REST Import Specification allows you to define specific parameters, which can be passed in the URL as a query string or in a request header field.
If you need to access a query parameter from UniBASIC code, you can do that with the following code fragment:
CALL KMK.GETHDR(QUERYHDRS$, 'NAME', L4.NAME)
If you need to access a parameter in the request header field from UniBASIC code, you can do that with the following code fragment:
CALL KMK.GETHDR(IHTTPHDRS$, 'X-Application-User', USERID)
To access a Kourier REST API, the user of the API must provide a Kourier REST Gateway user account name and a password. If there are multiple applications using the API, we recommend a separate user account for each application. This will allow you to revoke access to the API application without effecting access to the Kourier REST Gateway or other applications using the API. Remember, you must create unique credentials (user/password) for each Kourier REST Gateway user account for this approach to be workable.
In the client application that is accessing the REST API, the connection and credentials MUST be passed in the X-Connection and Authorization HTTP request header fields.
Handling concurrent access to records is quite common in transactional data management systems that can maintain state. However, Kourier REST services are “stateless” due to the nature of HTTP and RESTful principles. If your REST application only creates and reads data records concurrency control is not mandatory. However, if your REST application must modify or delete records, you need to decide on how to handle this situation.
The easiest approach is “the last change wins”. This implies that you just ignore any change that might have taken place between reading and modifying a record. However, this leads to the so called “lost update problem” – which for most business scenarios is obviously not acceptable. Kourier REST addresses concurrency control using a technique called Optimistic Locking. Kourier implements optimistic locking on REST resources using the HTTP headers “Etag” and “If-Match”.
An “Etag” is generated whenever a Kourier GET resource returns a single record. The value of the Etag encodes the version of the record used to create the representation of the resource. When a client application attempts to update (PUT) or delete (DELETE) a single record and the request includes an “If-Match” HTTP header Kourier will verify that the underlying record has not changed before allowing the request to proceed. If the underlying record has changed, the client application will receive a 412 Precondition Failed status code. The API designer can force a client application to specify the “If-Match” header by adding it as a parameter for the request and making it be a required field.
You use standard HTTP verbs to indicate the type of request you are making. These HTTP verbs directly correlate with the concept of database CRUD (Create, Read, Update, and Delete) operations.
HTTP Verb |
Specification |
Description |
GET |
Export |
Used to read information from your U2-based application via a U2 to REST Export Specification. |
POST |
Import |
Used to insert a record into your U2-based application via a XML to U2 Import Specification. |
PUT |
Import |
Used to update a record into your U2-based application via a XML to U2 Import Specification. |
PATCH |
Import |
Used to either insert or update a record into your U2-based application via a XML to U2 Import Specification. |
DELETE |
Import |
Used to delete a record into your U2-based application via a XML to U2 Import Specification. |
When making a request, query parameters can be used to pass additional information to a
Kourier Export or Import Specification responding to the request.Parameters are reserved solely for the use of the API designer except for the following:
Query Parameter |
Required |
Description |
Fields |
No | Used to limit the number of fields returned in the request result. This query parameter accepts a comma separated list of fields to include in the request result. If this query parameter is not included in the URL, all fields will be returned. |
InputAs |
No | Used to indicate the format of the request body. Possible values are: XML or JSON. If this query parameter is specified, it overrides the Content-Type header in the request. |
OutputAs |
No |
Used to control the format of the request result. Possible values are: TAB, XML, JSON, TILDE, PIPE, CSV, HTML, FIXED. If this query parameter is specified, it overrides the accept header in the request. |
Page |
No |
Used to control pagination of requests that return a large number of items. This query parameter takes a numeric value representing the first item to return in the record set. |
PerPage |
No |
Used to control pagination of requests that return a large number of items. This query parameter takes a numeric value representing the number of items to return in the result set. This number cannot be greater than the value returned in the X-Max-Items Header field. |
SortBy |
No |
Used to control the order in which items are returned in the request result. This query parameter accepts a comma separated list of field names each with a possible unary negative (-) to imply descending sort order. |
X-Connection |
Yes |
The name of the Kourier connection to use for this request. |
X-HTTP-Method-Override |
No |
For clients that only support HTTP GET and POST methods, this query parameter allows you to override the HTTP method. This query parameter is only valid on POST requests. |
Each request must contain certain required and optional information needed by Kourier to process the request. In some cases this information may be passed using the Reserved Query Parameters and in other cases this information must be passed in the HTTP header. Any HTTP header not in the list below will be ignored.
Header |
Type |
Required |
Description |
Accept |
ALL |
No |
Used to control the format of the request result. Possible values are: application/json, application/xml, text/html, text/csv, text/tab-separated-values, text/pipe, text/tilde, and text/fixed. |
Authorization |
ALL |
Yes |
The user ID and password associated with the Kourier connection base 64 encoded. Basic Auth only. |
Content-Type |
ALL |
No |
Used to indicate the format of the request body. Possible values are: application/json or application/xml. |
If-Match |
PUT and DELETE |
No |
Indicates that Kourier should enforce concurrency control. |
X-Enhanced-Errors |
ALL |
No |
A value of 1 indicates that enhanced response errors should be generated when exceptions are raised. |
X-HTTP-Method-Override |
POST |
No |
For clients that only support GET and POST HTTP methods, this request header allows you to override the HTTP method. This header is only valid on POST requests. |
X-Connection |
ALL |
Yes |
The name of the Kourier connection to use for this request. |
Kourier may return one or more of the response headers described below:
Header |
Request Type |
Always Returned |
Description |
Cache-Control |
ALL |
Yes |
Should always return no-cache |
Content-Length |
ALL |
Yes |
The length of the response body in bytes. |
Content-Type |
ALL |
Yes |
The MIME type of this content |
Date |
ALL |
Yes |
The date and time that Kourier returned results to the website. Example: |
Etag |
GET |
No |
An Etag is returned if a single record is returned in the response. Its value should be used when updating or deleting a resource if the If-Match header field is required. |
Expires |
All |
Yes |
Should always return -1 |
Links |
GET |
No |
Includes URLs to navigate to the first, previous, next, and/or last page of a result set. A link header is only returned if the number of items selected exceeds the EXPORT-MAX-ITEMS parameter. The only time the links are provided is if the X-Count-Items is greater than the X-Max-Items header. |
Pragma |
ALL |
Yes |
Should always return no-cache |
Server |
ALL |
No |
The web server software that managed the request. This header may be omitted based upon the website's configuration. |
Status |
ALL |
Yes |
The HTTP status of the response (see response code below). |
X-AspNet-Version |
ALL |
No |
ASP.NET version. This header may be omitted based upon the website's configuration. |
X-Kourier-Run |
ALL | Yes | This is the unique number for each time a request is processed on the U2 server. It can be used to correlate the REST statistics on the U2 server with a specific request in the gateway request log. If your application creates its own request log, store this number so that you can correlate an entry in your log with an entry in other REST logs. |
X-Kourier-Version |
ALL |
Yes |
Kourier version that processed the request. |
X-Rate-Limit-Remaining |
ALL |
Yes |
The number of requests remaining in the current rate limit window. |
X-Rate-Limit-Reset |
ALL |
Yes
|
The number of seconds before the rate limit window resets. |
X-Count-Items |
GET |
Yes |
Indicates the total number of items available in the request result (see also: Page, PerPage query parameters). |
X-Max-Items |
Get |
Yes |
Indicates the maximum number of items that can be returned in a single request result (see also: Page, PerPage query parameters). |
X-Powered-By |
ALL |
Yes |
Should always be ASP.NET |
Kourier will use standard HTTP response codes to indicate the status of the request.
Code |
Description |
200 |
Request was processed successfully. GET method only. |
201 |
Request was processed successfully. Resources were created or modified. POST, PUT, PATCH or DELETE methods. |
204 |
Request was processed successfully but no data returned. GET method only. |
400 |
There was a problem processing the request. The response body will contain additional information. |
401 |
The request was refused because the authentication information was not provided or is not valid. |
404 |
The requested resource could not be found. |
405 |
The requested HTTP method is not supported by the resource. |
412 |
The request was not processed because the underlying record was changed by another user. |
500 |
Server processing error. |
The format of the status response payload is sensitive to the Accept header passed in the request or as specified in the OUTPUTAS standard query parameter.
An accept type of JSON will return JSON.
An accept type of XML will return XML.
All other supported accept types (e.g. tab, csv, etc.) will return the status response payload as XML.
The format of a status response payload varies depending upon how the API developer decided to implement the resource/sub-resource and if the exception was raised by the Kourier REST Gateway or from the U2 Server.
The format of Kourier Gateway errors includes a unique message code for each type of error generated by the Kourier REST Gateway. Kourier REST Gateway errors will begin with the prefix “KGW”.
<?xml version="1.0" encoding="utf-16"?> <Status> <HttpStatus>404</HttpStatus> <MessageCode>KGW-410</MessageCode> <MessageText>RWS/CUSTOMERS6 is not a valid resource.</MessageText> </Status>
Here is a list of possible errors:
Error Code |
Description |
KGW-100 |
An unspecified authorization error occurred |
KGW-101 |
No authorization header specified |
KGW-102 |
No data in the authorization header |
KGW-103 |
Authorization header was not BASIC |
KGW-110 |
The user name specified was not found |
KGW-111 |
The user account specified is not active |
KGW-112 |
The password was not correct |
KGW-200 |
Rate limit exceeded |
KGW-300 |
The X-Connection header was not specified or invalid for the user |
KGW-400 |
No resource was specified |
KGW-404 |
A resource was specified but it is not a valid resource |
KGW-420 |
The user does not have permission for the specified verb on the specified resource |
KGW-500 |
Any unhandled exception |
KGW-600 |
UniRpc error with error ID of 80011,39129, or 81009 |
KGW-601 |
UniRpc other than 80011, 39129, or 81009 |
The format of interface exceptions generated from the U2 Server includes a unique message code for each type of error generated and may include a list of additional error information as shown below.
<Status> <HttpStatus>400 KOURIER</HttpStatus> <MessageCode>KMK-682</MessageCode> <MessageText>Query parameter CustomerNo is a required field. Value is “”.</MessageText> <Errors> <Error> <FieldName>CustomerNo</FieldName> <ErrorCode>KMK-902</ErrorCode> <ErrorText>CustomerNo is a required field.</ErrorText> <FieldIn>query</FieldIn> <FieldValue/> <FieldPosition/> </Error> </Errors> </Status>
The format of application exceptions generated from the U2 server when processing a POST, PUT, PATCH and DELETE request are similar to other exceptions raised by the U2 Server. However, the response may contain a Record node so that additional information may be report along with a list of errors associated with each record processed.
<Status> <HttpStatus>407 KOURIER</HttpStatus> <MessageCode>KMK-900</MessageCode> <MessageText>Request did not complete successfully.</MessageText> <Record> <ResourceFile>CUSTOMER</ResourceFile> <ResourceID>167</ResourceID> <RemoteID/> <Loaded>0</Loaded> <Operation>U</Operation> <Href/> <Errors> <Error> <FieldName>{AfterRead}</FieldName> <ErrorCode>XYZ-001</ErrorCode> <ErrorText>Record 167 may not be updated at this time</ErrorText> <FieldIn>body</FieldIn> <FieldValue>167</FieldValue> <FieldPosition>0,0,0</FieldPosition> </Error> <Error> <FieldName>{BeforeUpdate}</FieldName> <ErrorCode>ABC-001</ErrorCode> <ErrorText>Record “167” is on accounting hold and may not be updated.</ErrorText> <FieldIn>body</FieldIn> <FieldValue/> <FieldPosition>0,0,0</FieldPosition> </Error> </Errors> </Record> </Status>
Kourier REST subscriptions allow an API consumer to subscribe to data changes for a resource. REST subscriptions leverage Kourier’s net change capability to track changes for a resource and Kourier’s checksum capability to filter out records where the fields in the subscription have not changed (e.g. false positive net change records) since last delivered to the subscriber. Two subscription events are supported: UPDATE and DELETE.
The API consumer can create a subscription on a resource by POSTing a request to the SUBSCRIBE sub-resource. The POSTed URL MUST include any required query parameter(s) and may optionally include any of the following standard query parameters:
Fields - used to limit which fields are returned in the payload for the call back POST. This is useful when your application is not interested in all of the fields in the full resource representation. If not specified, all fields are returned.
OutputAs – used to declare the format (JSON or XML) of the payload. This can also be specified via the Accept HTTP header when creating the subscription.
PerPage – used to control the number or records returned in a payload. The value of this parameter may not be greater than the value of the X-Max-Items header returned when performing a GET on the resource.
The request body must include the call back URL element while all other elements are optional.
Sample URL: https://apiserver/version/resource/SUBSCRIBE
Sample Request XML:
<?xml version="1.0"?>
<Subscription>
<CallbackURL>https://mycompany/callbacks/loader.aspx</CallbackURL>
<CallbackAuth>S09SRBFBOklmbxkyeSQ=</CallbackAuth>
<Description>Customer sync with ASTRA</Description>
</Subscription>
The sample XML above creates a subscription where payloads are posted to the call back URL at “https:/mycompany/callbacks/loader.aspx”. Each payload posted to the call back URL will include the Basic Authorization header/value of “S09SRVFBOklmbXkyeSQ=”. For more information on creating a subscription, refer to the Implementing the SUBSCRIBE Method in a Resource and Create a Subscription for a RESOURCE using Postman topics.
When a subscription is created, the following tasks are completed:
Create a Kourier DSN named “.{gwuser}_resourceID”, if it does not exist, so that the callback URL, protocol and Basic Authorization HTTP header, if provided, can be stored. This will allow different callback URLs to be specified by resource. For more information, refer to the Subscription Data Source page.
Create a Kourier Schedule named “.{gwuser}_nnnn”, if it does not exist, which runs all subscriptions (services) for a specific gateway user on a recurring basis. For more information, refer to the Subscription Schedule page.
Enable net change tracking for the primary file associated with the resource via KCL.ADDLOG. The net change application ID will be “.{gwuser}_resourceID”.
Enable checksum for the application ID for the primary file associated with the resource via KCL.ADDCHECKSUM.
Update the KT_SUBSCRIPTIONS file.