Transport
Nirum currently only has one transport protocol which is based on HTTP and JSON.
Method calls
A method call is represented as an HTTP request. By default, it’s a simple
POST
request like the following:
POST /?method=method_name HTTP/1.1
Content-Type: application/json
{}
The above request is calling a service method named method-name
with
no arguments.
The method
parameter of the query string represents a method name to call.
It is a service method name. A client (which makes a request) has to normalize
the method name. The normalization rule is the same to serialization format’s
identifier normalization.
The request content body is a JSON payload, and it represents arguments to pass. It’s a JSON object that the keys are argument names. Keys also have to be normalized in the same identifier normalization rule to serialization format. Each value is a serialized corresponding Nirum value according to the Nirum serialization format.
Here are some rules that are applied to client and server differently (it is a kind of robustness principle):
End | Client (serializer) | Server (deserializer) |
---|---|---|
Argument names | Have to normalize | Allow non-normalized names |
Optional arguments | Do not omit if null |
Treat as null if omitted |
Unknown arguments | Include only known ones | Simply ignore unknown ones |
The following is another example to call a service method named notify
with some arguments. The former code is a Nirum interface and the latter is
an HTTP request:
unboxed email-address (text);
unboxed phone-number (text);
union contact = email (email-address address)
| telephone (phone-number number)
;
service notification-service (
notify ({contact} recipients, text title, text? content)
);
POST /?method=notify HTTP/1.1
Content-Type: application/json
{
"recipients": [
{
"_type": "email",
"address": "john.doe@example.com"
},
{
"_type": "telephone",
"number": "+1 541-754-3010"
}
],
"title": "Our product is now 15% cheaper",
"content": "See also our new pricing table!"
}
Return values
A method may return a value or not. If it does not have a return type
an HTTP response to an HTTP request that calls it should be simply null
:
HTTP/1.1 200 OK
Content-Type: application/json
null
The status code 200 OK
indicates the method call is successful.
Even if it responds with any other value a client should simply ignore that.
If a method does have a return value an HTTP response to an HTTP request that calls it should be a JSON payload that serializes a returned value which is a serializaed Nirum value according to the Nirum serialization format.
The following examples show a method, a request to call it, and its response:
record product (
uuid id,
text name,
int32 stock,
);
service product-service (
product? find-product (uuid product-id)
);
POST /?method=find-product HTTP/1.1
Content-Type: application/json
{
"product_id": "9926eb5a-3893-4aee-ab19-23ebd1a1292e"
}
HTTP/1.1 200 OK
Content-Type: application/json
{
"id": "9926eb5a-3893-4aee-ab19-23ebd1a1292e",
"name": "White shirt",
"stock": 100
}
As find-product
method’s return type is optional (notice the trailing ?
),
it may return null
as well:
HTTP/1.1 200 OK
Content-Type: application/json
null
Error values
A method may throws
a value or not. If it has an error type that follows
a throws
keyword a response should be either a return value or an error value.
If response’s status code is 200 OK
a JSON payload in the content contains
a return value.
If the status code starts with 4
or 5
(e.g., 400 Bad Request
) a JSON
payload in the content contains an error value. Similar to return values,
error values also are a serialized Nirum value according to
the Nirum serialization format.
The following examples show a method, a request to call it, and its response with an error value:
record product (
uuid id,
text name,
int32 stock,
);
@error
@http-status(code="404")
unboxed product-not-found (text);
service product-service (
product find-product (uuid product-id) throws product-not-found
);
POST /?method=find-product HTTP/1.1
Content-Type: application/json
{
"product_id": "9926eb5a-3893-4aee-ab19-23ebd1a1292e"
}
HTTP/1.1 404 Not Found
Content-Type: application/json
"There is no product with an ID \"9926eb5a-3893-4aee-ab19-23ebd1a1292e\"."
Note that the status code is not 200 OK
but 404 Not Found
. The JSON payload
in the response content serializes a Nirum value of product-not-found
type.