Serving Resources
Chapter 3: How to handle get requests to serve models and collectionsThe Hello World example showed how to serve a simple model. Let’s learn how it works.
Get requests
A get request1 from Resgate is similar to a HTTP GET request. It differs that it is sent over NATS instead of HTTP, and that the response must be a JSON object with a certain structure.
To listen for get requests, the service must subscribe to a subject with the pattern:
get.<resource>
Where resource
is the the resource ID (as described as in previous chapter).
Listening for requests on the resource ID example.foo
would look like this:
nats.subscribe('get.example.foo', (msg, reply) => { /* ... */ });
Tip
Wildcard subscriptions can be used for ID parameters:
nats.subscribe('get.inventory.item.*', (msg, reply, subject) => { /* Parse subject for the item ID */ });
The message data, msg
, is a JSON object that may have the following property:
query
- optional query part of the resource ID explained in Advanced Topics - Query Resources
The response2 structure depends on if the response is a model, a collection, or an error.
Model response
If the resource is a model (same as in the Hello World example), the response should have the following structure:
{
"result": {
"model": { /* model data */ }
}
}
And in code, it might look like this:
nats.subscribe('get.example.foo', (req, reply) => {
nats.publish(reply, JSON.stringify({
result: {
model: { foo: "baz", bar: 42 }
}
}));
});
Collection response
If the resource is a collection, the response is slightly different:
{
"result": {
"collection": [ /* collection data */ ]
}
}
And in code, it might look like this:
nats.subscribe('get.example.bar', (msg, reply) => {
nats.publish(reply, JSON.stringify({
result: {
collection: [ 12, "bar", null ]
}
}));
});
Warning
Collections and models must not contain other collections or models. You are not allowed to send:
[ { "id": 1, "name": "foo" }, { "id": 2, "name": "bar" }, ]
We explain how to solve nested/complex data structures in Chapter 8 - Nested resources.
Error response
In case of an error, most commonly Not Found or Internal Error, the response may look like this:
{
"error": {
"code": "system.notFound",
"message": "Not Found"
}
}
Look at the pre-defined errors3 in the specification for a full list of error codes.
Access requests
Unlike with HTTP requests, access control is handled in a separate request called an access request4. This will be described more in detail in Chapter 7 - Access control.
To allow anyone to get our example resources, we can use a wildcard subscription that grants full access:
nats.subscribe('access.example.>', (msg, reply) => {
nats.publish(reply, JSON.stringify({ result: { get: true, call: "*" }}));
});