Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

...

...

...

Table of Contents

Introduction

The support for invoking Business Tasks and Business Entity Methods through the RESTful interface is based on the requirements described in this article: RESTful services. Particularly the RestEntitiesWebHandler and the RestResourceService (as a Service Instance of the IRestResourceService). 

Business Task methods and Business Entity methods are exposed as RESTful resources using the same set of annotations - and actually share a lot of similarities. Business Entity invokable methods are typically PUBLIC VOID methods with a ProDataset INPUT-OUTPUT parameter and a (JSON serializable) parameter object. Business Task methods are typically PUBLIC VOID methods with zero to five ProDataset INPUT-OUTPUT parameters and a (JSON serializable) parameter object. 

Info
title

Support for return value of Business Task and Business Entity Methods

Also to facilitate the support for RESTful invocation of Business Task and Business Entity methods the Consultingwerk.OERA.ServiceInterface:InvokeTask API has been enhanced with support for returning the return value of a method to the caller. This finally allows developers to separate the request message from the response message.

The InvokeTask API is fully capable of invoking Business Entity methods as well.

...

Code Block
languagec#
CLASS Consultingwerk.SmartComponentsDemo.OERA.Sports2000.CustomerBusinessEntity
    INHERITS SmartBusinessEntity IMPLEMENTS IFetchDataByReference, ISupportsRestAddress, ISupportsRestMethods:

...

Invokable methods

RESTful interfaces Valid signatures for Business Entity methods are defined by a @RestMethod annotations attached to the method (just before the METHOD block). 

...

languagec#

...

methods that can be invoked using the RESTful interface must have the following characteristics:

  • Zero to five INPUT-OUTPUT datasets or dataset handles.

  • Zero or one INPUT parameter object. If used, the parameter object must be the last parameter defined.

  • A void return value, or an OOABL type that is serializable to JSON (typically using the Consultingwerk.IJsonSerializable interface).

This includes methods that take no inputs and return no values, as well as methods that have only a single dataset INPUT-OUTPUT parameter.

Defining RESTful interfaces for invokable methods

RESTful interfaces for Business Entity methods are defined by a @RestMethod annotations attached to the method (just before the METHOD block). 

Code Block
languagec#
    @RestMethod (address="/Customers/~{CustNum}/PutCustomerOnHold", requestMethod="get", parameterClassName="Consultingwerk.SmartComponentsDemo.OERA.Sports2000.PutOnHoldParameter", response="dsCustomer").
    /*------------------------------------------
------------------------------------
        Purpose: Puts the Customer on hold
        Notes:   Client callable method
        @param dsCustomer INPUT-OUTPUT DATASET
        @param poParameter The Parameter Object for this method
    ------------------------------------------------------------------------------*/
    METHOD PUBLIC VOID PutCustomerOnHold (INPUT-OUTPUT DATASET dsCustomer,
                                          poParameter AS PutOnHoldParameter):

Arguments of the @RestMethod annotation

The annotation provides the following arguments:

...

mapHeaders

...

Every invokable method may be annotated with more than a single @RestMethod annotation to provide alternative URI's for the same method.

Arguments of the @ParameterSchema annotation

When Business Task methods are configured to return a Dataset as the method response, it's required to provide an XSD file with the ProDataset schema to be included in the method documentation, e.g.:

...

The name of the dataset

...

The path reference to the dataset schema

...


    ------------------------------------------------------------------------------*/
    METHOD PUBLIC VOID PutCustomerOnHold (INPUT-OUTPUT DATASET dsCustomer,
                                          poParameter AS PutOnHoldParameter):

Arguments of the @RestMethod annotation

The annotation provides the following arguments:

Argument/Attribute

Mandatory

Description

address

no

The URI pattern to invoke the method. When not specified the pattern /{methodName} is used by default

ParameterClassName

no

The name of the parameter class to instantiate for calling into the method. When not specified, the OOABL type name of the parameter is used. In either case, if the type name is not instantiable - if it's an interface, enum or abstract class - then a Consultingwerk.Exceptions.InvalidValueException will be raised.

RequestMethod

no

The http method for the call described by this annotation. When not specified, get will be assumed as the default.

Request

no

Comma delimited list of the components from the JSON request body of the REST request. Components are "parameter" and the names of the ProDataset parameters.

Response

yes

Comma delimited list of the components for the JSON response of the REST request. Components are "return", the names of the ProDataset parameters and the name of the parameter.

If only a single ProDataset is provided, it may have additional modifiers.

  • :no-envelope added to the dataset name, to indicate that the dataset name is not returned as part of the response.

  • :<table-name> added to the dataset name, to indicate that only data for that table should be returned. A JSON array is returned, without any envelope (ie table or dataset names). If there is no data in the table, an empty JSON array is returned. If the table does not exist in the dataset, a Consultingwerk.OERA.RestResource.RecordNotFoundException is raised.

  • :<table-name>:first added to the dataset name, to indicate that only a single record in a table should be returned. A JSON object is returned, without any envelope (ie table or dataset names). If there is no data in the table, an empty JSON obejct is returned. If the table does not exist in the dataset, a Consultingwerk.OERA.RestResource.RecordNotFoundException is raised.

mapHeaders

no

Comma-delimited list of HTTP header names that are set as values on the method parameter object.. The header names may have an optional mapped property name, delimited by =.  For example, a value of Accept-Language=Language,Content-Disposition sets the values of the Accept-Language and Content-Disposition headers from the web request to properties named Language and Content-Disposition.

mapCookies

no

Comma-delimited list of HTTP cookie names to be set as values on the method parameter object. The cookie names may have an optional mapped property name, similar to the mapHeaders value. For example, a value of JSESSIONID=SessionId will set the value of the JSESSIONID cookie to a property named SessionId on the parameter object.

tags

no

Comma-separated list of tags used for grouping endpoints in Swagger documentation.

requestParameterSchemaType

no

An alternate name to use for the (input) parameter class in the Swagger documentation. This allows details of the implementation to be hidden. If not provided, the parameter's OOABL class name is used.

responseSchemaType

no

An alternate name to use for the return value class in the Swagger documentation. This allows details of the implementation to be hidden. If not provided, the OOABL type name of the return value is used.

propertyFrom

no

Comma-delimited list of values indicating how property values for a parameter class should be provided. Each entry has the format <property-name>:[query|hidden] . A value of query indicates that a query string is used. A value of hidden indicates that a value for that property is not expected to be sent by a client.

description

no

A description for the operation used in the Swagger documentation

Every invokable method may be annotated with more than a single @RestMethod annotation to provide alternative URI's for the same method.

Arguments of the @ParameterSchema annotation

When Business Task methods are configured to return a Dataset as the method response, it's required to provide an XSD file with the ProDataset schema to be included in the method documentation, e.g.:

Argument/Attribute

Mandatory

Description

datasetname

yes

The name of the dataset

schemafile

yes

The path reference to the dataset schema

datasetSchemaType

no

An alternative name used to provide the name of the ProDataSet schema generated as properties of the components.schemas object in the generated Swagger document. If not provided, a combination of the Business Entity or Business Task class name and the dataset name is used, in the format <entityname>-<datasetname> .

The @ParameterSchema annotation is optional. 

Arguments of the @RestMethodParameter annotation

Parameters passed into the method may receive a meaningful description for Swagger documentation provided by a RestMethodParameter annotation. Each parameter should have its own annotation.

Argument/Attribute

Mandatory

Description

name

yes

The name of the parameter. May also be parameter if the method’s parameter is a JsonObject.

description

yes

A description for the parameter

The @RestMethodParameter annotation is optional. 

Arguments of the @ApiDoc annotation

A Business Entity or Business Task may use an ApiDoc annotation to provide additional information for the generated Swagger documentation, for the whole class.

Argument/Attribute

Mandatory

Description

tags

no

Comma-separated list of tags used for grouping endpoints in Swagger documentation.

entitySchemaType

no

An alternate name to use for the Business Entity or Business Task class name in the Swagger documentation. This allows details of the implementation to be hidden. If not provided, the Business Entity or Business Task class name is used. This value is used to generate schemas that will be re-used: these appear as properties of the components.schemas object in the generated document.

The @ApiDoc annotation is optional. 

Population of the Parameter object

The REST request to the annotated method will be used to populate the properties of the method's parameter object using the following sources:

  1. For GET requests, the query string is first parsed and query string values will be used to populate the same named properties of the parameter object

  2. For all other request methods, e.g. POST, the request entity (request payload) - when the request entity represents a JSON object - is used to deserialize a JSON serializable parameter object.

  3. For all request methods (GET, POST, ...), the path parameter arguments are also assigned to properties of the parameter object. This is performed at the end, so that path parameters, as the strongest component of the request URI, overwrite properties assigned by query string components or deserialized form the request entity (request payload).  

Population of the JSON response of the request

...

GET http://localhost:8820/web/Entities/GetCustomerAndInvoices/1

POST http://localhost:8820/web/Entities/GetCustomerAndInvoices with a JSON payload like: 

Code Block
languagejs
"poParameter": {
    "Value": 1
  },
"dsCustomer": {
   "eCustomer": [
    {
		"CustNum": 1,
		"Country": "USA",
		"Name": "Lift Line Skiing",
		"Address": "Unter Käster 1",
		"Address2": null,
		"City": "Chicago",
		"State": "MA",
		"PostalCode": "01730",
		"Contact": "Gloria Shepley",
		"Phone": "(617) 450-0086",
		"SalesRep": "HXM",
		"CreditLimit": 0,
		"Balance": 50000,
		"Terms": "PREPAID ONLY",
		"Discount": 35,
		"Comments": "Put on hold: 25.06.2019 07:46:59\ntest",
		"Fax": "",
		"EmailAddress": "info@lift-tours.com",
		"Flags": "C",
		"SmartRecordKey": "000000001",
		"SmartAttachments": true,
		"SmartComments": false,
		"SmartCopiedFrom": ""
	}
  ]
},
"dsInvoice": {
  "eInvoice": [
	{
	"Invoicenum": 6,
	"CustNum": 1,
	"InvoiceDate": "2009-02-09",
	"Amount": 1829.5,
	"TotalPaid": 1829.5,
	"Adjustment": 0,
	"OrderNum": 6,
	"ShipCharge": 0
	},
	{
	"Invoicenum": 79,
	"CustNum": 1,
	"InvoiceDate": "2008-11-19",
	"Amount": 34707.84,
	"TotalPaid": 34707.84,
	"Adjustment": 0,
	"OrderNum": 79,
	"ShipCharge": 0
	},
	{
	"Invoicenum": 146,
	"CustNum": 1,
	"InvoiceDate": "2009-02-28",
	"Amount": 4605.91,
	"TotalPaid": 0,
	"Adjustment": 0,
	"OrderNum": 177,
	"ShipCharge": 0
	}
  ]
}

...