Basic Concepts
Chapter 2: Introduction to basic concepts and technologies used with ResgateResources
Resgate and the RES protocol is built around a concept of resources1, similar to the JSON data sent over REST APIs.
There are two types of resources:
- Models
- Collections
Models
A model2 is unordered key/value data represented by a JSON object, and may look like this:
{
"id": 42,
"name": "Jane Doe",
"isAdmin": true
}
There are no restrictions on the property names (keys), but the values3 should be JSON primitives:
- string (
"foo"
) - number (
3.14
) - boolean (
true
) - null (
null
)
A value might also be something called a data value, as described below, or a resource reference4, but that will be described later in Chapter 8 - Nested Resources.
Collections
A collection5 is an ordered list represented by a JSON array, and may look like this:
[ 12, "foo", null ]
As the example above shows, a collection may contain values3 of mixed types.
Just like with model values, a collection may only contain JSON primitives, data values, or resource references3 which we’ll get back to in Chapter 8 - Nested Resources.
Data values
A model or collection usually contains primitive values.
But objects and arrays (eg. {"foo":["bar"]}
) requires a wrapper object with a single "data"
key.
A model with an array value may look like this:
{ // Good
"name": "Jane Doe",
"roles": { "data": [ "admin", "moderator" ] }
}
{ // Bad
"name": "Jane Doe",
"roles": [ "admin", "moderator" ]
}
This is called a data value6, and is used for storing any type of JSON data as a value.
Note
Data values cannot be partially updated like models or collections. If you want to add something to a data value array/object, you need to replace the entire array/object.
Resource IDs
Each resource is identified by a unique ID called resource ID7, or rid for short. It serves the same purpose as the URL path in a REST API. A resource ID may look like this:
inventory.item.42
It is an alpha-numeric text string consisting of dot-separated parts, instead of slash as used in URLs. The example above consists of three parts: inventory
, item
, and 42
.
Resource IDs may also contain an optional query part, which is covered by the Advanced Topic - Query Resources.
Tip
The first part of a resource ID should be the unique name of the service that serves the resource.
This will help in avoiding naming conflicts between multiple microservices.
NATS Server
NATS Server is a simple and highly efficient messaging system8 used for communication between services and Resgate. It is the close companion to Resgate. Without a NATS server to connect to, Resgate won’t even start.
Publish/Subscribe
NATS uses the publish/subscribe pattern for communication, which means that anyone connected to NATS, be it a service or a Resgate, may both publish messages on any subject:
nats.publish('my.subject', "Hello world");
Or subscribe to messages, based on the subject of the message:
nats.subscribe('my.subject', msg => {
console.log("Message: " + msg);
});
Request/Reply
NATS may also be used for request/reply patterns, allowing request to be sent on a subject:
nats.request('my.request', "Help!", {max: 1}, resp => {
console.log("Response: " + resp)
});
And anyone subscribing to that subject (my.request
) may send a reply back to the original requester:
nats.subscribe('my.subject', (msg, reply) = {
nats.publish(reply, "I can help");
});
Wildcard subscriptions
NATS allows the usage of wildcards when subscribing.
Asterisk (*
) matches any part, at any level of the subject:
nats.subscribe('foo.*.baz', (msg, reply, subject) => {
// Matches subject 'foo.bar.baz', 'foo.bax.baz', etc.
});
Greater than (>
) matches any length of the tail of a subject, and can only be the last part:
nats.subscribe('foo.>', (msg, reply, subject) => {
// Matches subject 'foo.bar', 'foo.bar.baz', 'foo.foo.bar.bax.22', etc.
});