Basic Concepts

Chapter 2: Introduction to basic concepts and technologies used with Resgate

Resources

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.
});