Formatting datasets returned by RESTful Business Service methods

https://consultingwerk.atlassian.net/wiki/spaces/SCL/pages/8094254 descibes how a business task method annotated with the @RestMethod annotation can return datasets to a caller. Any datasets returned using the response="<dataset-name>" anotation attribute are formatted using the ABL's standard formatting, as applied when calling the WRITE-JSON methodon the dataset.

The Consultingwerk.OERA.RestResource.IRestResourceFormatService service exists to perform formatting of datasets (and other kinds of responses). This service is used to format responses for standard https://consultingwerk.atlassian.net/wiki/spaces/SCL/pages/8094560 .

Method

Return type

Parameters

Method

Return type

Parameters

BuildCollectionResponse (HANDLE, CHARACTER, IRestResourceFormatParameter)

JsonArray

  1. A handle to the dataset to format

  2. A sort string to order the primary table’s records. Either an empty string or an ABL sort phrase beginning with BY

  3. An instance of format parameters

BuildRecordResponse (HANDLE, IRestResourceFormatParameter)

JsonObject

  1. A handle to the dataset to format

  2. An instance of format parameters

BuildCountResponse (ICountRecordsRequest, IRestResourceFormatParameter)

JsonObject

  1. An instance of the count records request

  2. An instance of format parameters

BulidStatusResponse (CHARACTER, OpenEdge.Net.HTTP.StatusCodeEnum, IRestResourceFormatParameter)

JsonObject

  1. A message string

  2. The HTTP status code for the response

  3. An instance of format parameters

Each method takes an instance of a rest resource format parameter (Consultingwerk.OERA.RestResource.IRestResourceFormatParameter) that provides information to the formatting service on what information to provide in the response. The default implementation is the Consultingwerk.OERA.RestResource.RestResourceFormatParameter class.

There are a number of properties that can be set on the parameter object.

Property name

Required

Data type

Purpose

Property name

Required

Data type

Purpose

RestAddress

YES

CHARACTER

The URI template or relative address used to access this resource. Eg "/Customers/{CustNum}" . Used for formatting / building the self and other links

Tables

YES

CHARACTER

A comma-separated list of tables in the dataset to be returned

IdField

YES

CHARACTER

A comma delimited list of fields used to return the ID of a resource

Fields

YES

CHARACTER

The comma delimited list of fields to be added to the response. Possible values may be field names, tablename.fieldname's or tablename.*

ChildAddresses

NO

CHARACTER

Links to resource URI's for the child records returned by the request, comma delimited list, entries are in the form of {tablename}:{uri pattern} . e.g.

eSalesrep:/Salesreps/~{SalesRep}

Links

NO

CHARACTER

HATEOAS style links (to other business entities) in the form of {rel}:{uri pattern} , e.g.

orders:/Customers/~{CustNum}/Orders,salesrep:/Salesreps/~{SalesRep}

Values

NO

Consultingwerk.ListNameValuePair

A list of address tokens and their mapped values (in the URL)

Request

YES

OpenEdge.Web.IWebRequest

The request made to access the current resource

AddSelfUrl

NO

LOGICAL

Indicates whether to add a resource's "self” url to the response

The mandatory properties are enforced by constructor.

Using the rest resource formatting service

When applications call the formatting service from an annotated business service method, the response attribute of the @RestMethod annotation must include "return" and the return value of the method must be a JSON construct (either JsonObject or JsonArray).

@RestMethod (address="/GetCustomerAndInvoices", requestMethod="get", parameterClassName="Consultingwerk.IntegerHolder", response="return"). @ParameterSchema (datasetname="dsCustomer", schemafile="Consultingwerk/SmartComponentsDemo/OERA/Sports2000/dsCustomer.xsd"). @ParameterSchema (datasetname="dsInvoice", schemafile="Consultingwerk/SmartComponentsDemo/OERA/Sports2000/dsInvoice.xsd"). METHOD PUBLIC JsonObject GetCustomerAndInvoices (INPUT-OUTPUT DATASET dsCustomer, INPUT-OUTPUT DATASET dsInvoice, poParameter AS IntegerHolder): DEFINE VARIABLE oRestResourceFormatService AS IRestResourceFormatService NO-UNDO. DEFINE VARIABLE oRestResourceFormatParameter AS IRestResourceFormatParameter NO-UNDO. DEFINE VARIABLE oResponse AS JsonObject NO-UNDO. DEFINE VARIABLE oRequest AS OpenEdge.Web.IWebRequest NO-UNDO. /* Perform business task here */ ServiceInterface:FetchData (SmartComponentsDemoServices:OERA:Sports2000:CustomerBusinessEntity, NEW FetchDataRequest ("eCustomer":U, SUBSTITUTE ("for each eCustomer where eCustomer.CustNum = &1":U, QUOTER (poParameter:Value))), OUTPUT DATASET dsCustomer) . ServiceInterface:FetchData (SmartComponentsDemoServices:OERA:Sports2000:InvoiceBusinessEntity, NEW FetchDataRequest ("*":U, SUBSTITUTE ("for each eInvoice where eInvoice.CustNum = &1":U, QUOTER (poParameter:Value))), OUTPUT DATASET dsInvoice) . /* Format datasets for return */ oRestResourceFormatService = {Consultingwerk/get-service.i IRestResourceFormatService "NEW RestResourceFormatService()"}. oResponse = NEW JsonObject(). /* The webrequest is immutable for this request */ oRequest = NEW OpenEdge.Web.WebRequest(). /* Add the customer dataset */ oRestResourceFormatParameter = NEW RestResourceFormatParameter("/Customers/~{CustNum}":U, "eCustomer":U, "eCustomer.CustNum,eCustomer.Name,eCustomer.Balance":U, "CustNum":U, oRequest, ?). oResponse:Add("customers", oRestResourceFormatService:BuildRecordResponse(DATASET dsCustomer:HANDLE, oRestResourceFormatParameter)). /* Add the invoice dataset */ oRestResourceFormatParameter = NEW RestResourceFormatParameter("/Invoices/~{InvNum}":U, "eInvoice":U, "eInvoice.*":U, "InvNum":U, oRequest, ?). oResponse:Add("invoices":U, oRestResourceFormatService:BuildCollectionResponse(DATASET dsInvoice:HANDLE, "BY eInvoice.InvoiceDate":U, oRestResourceFormatParameter)). RETURN oResponse. END METHOD.