Transmission content

All data is transmitted as JSON arrays or objects, according to the requested URI.

We'll discuss how data is expected to be transmitted, at the application level.

Request format

As stated above, there are several available modes of routing, defined by a given class, inheriting from TSQLRestServerURIContext:

TSQLRestRoutingREST TSQLRestRoutingJSON_RPC
Description RESTful mode JSON-RPC mode
Default Yes No
URI scheme /Model/Interface.Method[/ClientDrivenID]
or /Model/Interface/Method[/ClientDrivenID]
+ optional URI-encoded params
/Model/Interface
Body content JSON array of parameters
or void if parameters were encoded at URI
"method":"MethodName",
"params":[...]
[,"id":ClientDrivenID]
Security RESTful authentication for each method
or for the whole service (interface)
RESTful authentication for the whole service (interface)
Speed 10% faster 10% slower

The routing to be used is defined globally in the TSQLRest.ServiceRouting property, and should match on both client and server side, of course. Of course, you should never assign the abstract TSQLRestServerURIContext to this property.

REST mode

In the default TSQLRestRoutingREST mode, both service and operation (i.e. interface and method) are identified within the URI. And the message body is a standard JSON array of the supplied parameters (i.e. all const and var parameters).

Here is typical request for ICalculator.Add:

 POST /root/Calculator.Add
(...)
[1,2]

Here we use a POST verb, but the framework will also allows other methods like GET, if needed (e.g. from a regular browser). The pure Delphi client implementation will use only POST.

For a sicClientDriven mode service, the needed instance ID is appended to the URI:

 POST /root/ComplexNumber.Add/1234
(...)
[20,30]

Here, 1234 is the identifier of the server-side instance ID, which is used to track the instance life-time, in sicClientDriven mode. One benefit of transmitting the Client Session ID within the URI is that it will be more secure in our RESTful authentication scheme: each method (and even any client driven session ID) will be signed properly.

In this TSQLRestRoutingREST mode, the server is also able to retrieve the parameters from the URI, if the message body is left void. This is not used from a Delphi client (since it will be more complex and therefore slower), but it can be used for a client, if needed:

 POST root/Calculator.Add?+%5B+1%2C2+%5D
GET root/Calculator.Add?+%5B+1%2C2+%5D

In the above line, +%5B+1%2C2+%5D will be decoded as [1,2] on the server side. In conjunction with the use of a GET verb, it may be more suitable for a remote AJAX connection.

As an alternative, you can encode and name the parameters at URI level, in a regular HTML fashion:

 GET root/Calculator.Add?n1=1&n2=2

Since parameters are named, they can be in any order. And if any parameter is missing, it will be replaced by its default value (e.g. 0 for a number or '' for a string).

This may be pretty convenient for simple services, consummed from any kind of client.

Note that there is a known size limitation when passing some data with the URI over HTTP. Official RFC 2616 standard advices to limit the URI size to 255 characters, whereas in practice, it sounds safe to transmit up to 2048 characters within the URI. If you want to get rid of this limitation, just use the default transmission of a JSON array as request body.

As an alternative, the URI can be written as /RootName/InterfaceName/MethodName. It may be more RESTful-compliant, depending on your client policies. The following URIs will therefore be equivalent to the previous requests:

 POST /root/Calculator/Add
POST /root/ComplexNumber/Add/1234
POST root/Calculator/Add?+%5B+1%2C2+%5D
GET root/Calculator/Add?+%5B+1%2C2+%5D
GET root/Calculator/Add?n1=1&n2=2

From a Delphi client, the /RootName/InterfaceName.MethodName scheme will always be used.

JSON-RPC

If TSQLRestRoutingJSON_RPC mode is used, the URI will define the interface, and then the method name will be inlined with parameters, e.g.

 POST /root/Calculator
(...)
{"method":"Add","params":[1,2],"id":0}

Here, the "id" field can be not set (and even not existing), since it has no purpose in sicShared mode.

For a sicClientDriven mode service:

 POST /root/ComplexNumber
(...)
{"method":"Add","params":[20,30],"id":1234}

This mode will be a little bit slower, but will probably be more AJAX ready.

It's up to you to select the right routing scheme to be used.

Feedback is welcome in our forum, as usual!