Methods
Chapter 6: How to define and call methods on a resourceEach resource may have methods that can be called remotely through a call request1. It is in many ways similar to a HTTP POST request. Let’s have a look at it.
Call requests
To listen for call requests, the service subscribes to a subject with the following pattern:
call.<resource>.<method>
Where resource
is the resource ID and method
is the alphanumeric (no dots!) name you’ve given to the method.
In code, listening to calls to method mymethod
on resource example.foo
would look like this:
nats.subscribe('call.example.foo.mymethod', (msg, reply) => {
/* Handle the request and send a response */
});
Request message
The call request’s message is a JSON object with the following properties:
params
- method parameters as sent by the clientcid
- connection ID string, generated by Resgate, and unique for every client connectiontoken
- access token. Will be explained in Chapter 7 - Access controlquery
- optional query part of the resource ID explained in Advanced Topics - Query ResourcesisHttp
- boolean true if the request is sent during a HTTP request, explained in Advanced Topics - Setting HTTP headers.
The message of a call request may look like this:
{
"params": { "foo": "bar", "baz": 42 },
"cid": "bhrq7ht8smgioj39ibr0",
"token": null
}
Successful response
If the call is successful, the service sends a response2 with either a static result, or a resource reference.
A resource references will be resolved by Resgate, so by the time the client gets the response from the call, it will not just be a reference, but the actual resource. Whereas a static result will be passed untouched to the client.
Result
A result response is a JSON object with the following property:
result
- result data as determined by the method. May be null.
In code it could look like this:
nats.subscribe('call.maths.utils.add', (msg, reply) => {
let { params } = JSON.parse(msg);
nats.publish(reply, JSON.stringify({
result: params.a + params.b
}));
});
Resource
A resource response is a JSON object with the following property:
resource
- resource reference3 which is an object with a single rid string property.
In code it could look like this:
nats.subscribe('call.inventory.createItem', (msg, reply) => {
let { params } = JSON.parse(msg);
let item = createNewInventoryItem(params);
nats.publish(reply, JSON.stringify({
resource: { rid: 'inventory.item.' + item.id }
}));
});
Note
An HTTP POST request getting a resource response will result in an empty HTTP response body with a Location HTTP header containing the url to the referenced resource:
HTTP/1.1 200 OK Location: /api/inventory/item/42
Error response
In case of an error, such as Invalid parameters or Method not found, the response2 may look like this:
{
"error": {
"code": "system.invalidParams",
"message": "Invalid parameters"
}
}
Look at the pre-defined errors4 in the specification for a full list of error codes.
Tip
If you use a custom error, the first part of the error code should be the unique name of the service.
This will help in avoiding naming conflicts between multiple microservices.
Pre-defined methods
The RES protocol describes pre-defined call methods5 that may be used for specific purposes. Let’s go through them.
Set call request
A set request6 may be used to update or delete a model’s properties. While the service is free to update a model at any time, triggered by any server-side event or client-side request, the set method is reserved for this purpose. This is to define a common way to update models. The subject has the method set
:
call.<resource>.set
The parameters should be a JSON object where each property being the new value to set on the model. If a model property is to be deleted, a delete action7 should be sent by the client instead of a new or null value.
In case some model properties were changed, a model change event8 must be sent as described in Chapter 4 - Model Events. You must make sure the event is sent before the call response.
The response itself is the same as for custom call requests, described earlier in this chapter.
Tip
In case a different parameter structure is required, eg. for a compare-and-swap kind of update, it is recommended to create a custom method to handle that request.
By keeping the
set
parameters standardized, it is easier to create clients with generic CRUD operations.