### Install Resgate via Docker
Source: https://resgate.io/docs/get-started/installation
This snippet demonstrates how to set up and run Resgate using Docker containers. It includes commands to create a Docker network, start a NATS server, and then run Resgate, connecting it to the NATS server. This method simplifies the setup process by managing dependencies within containers.
```bash
docker network create res
docker run -d --name nats -p 4222:4222 --net res nats
docker run --name resgate -p 8080:8080 --net res resgateio/resgate --nats nats://nats:4222
```
--------------------------------
### Resgate Successful Startup Output
Source: https://resgate.io/docs/get-started/installation
This example displays the typical output logs when the Resgate server starts successfully. It indicates the version, successful connection to the NATS server, the HTTP address it's listening on, and confirmation that the server is ready. This output is useful for verifying a correct Resgate setup.
```log
2006/01/02 15:04:05.786375 [INF] Starting resgate version 1.8.0
2006/01/02 15:04:05.869360 [INF] Connecting to NATS at nats://127.0.0.1:4222
2006/01/02 15:04:05.874344 [INF] Listening on http://0.0.0.0:8080
2006/01/02 15:04:05.875345 [INF] Server ready
```
--------------------------------
### Install Resgate from Source using Go
Source: https://resgate.io/docs/get-started/installation
This code snippet shows how to install Resgate by building it directly from its source code using the Go programming language's install command. Ensure you have Go installed before running this command. It fetches the latest version of Resgate and compiles it.
```go
go install github.com/resgateio/resgate@latest
```
--------------------------------
### Get Request Payload Example
Source: https://resgate.io/docs/specification/res-service-protocol
An example of the payload for a get request. It primarily consists of the 'query' parameter, which is the query part of the resource ID without the question mark. This parameter is mandatory if the resource ID has a query.
```json
{
"query": "resource/query/parameters"
}
```
--------------------------------
### Access Request Result Example
Source: https://resgate.io/docs/specification/res-service-protocol
This example shows the possible results of an access request. It indicates whether the client has 'get' (read) access and a comma-separated list of methods the client is allowed to 'call'. An asterisk '*' signifies permission to call any method.
```json
{
"get": true,
"call": "set,foo,bar"
}
```
--------------------------------
### Subscribe to GET Requests with Wildcards
Source: https://resgate.io/docs/writing-services/03serving-resources
This example shows how to use wildcard subscriptions for resource IDs, allowing a service to handle requests for multiple resources with a common pattern. The wildcard '*' can be used to capture parts of the subject.
```nats
nats.subscribe('get.inventory.item.*', (msg, reply, subject) => {
/* Parse subject for the item ID */
});
```
--------------------------------
### Install ResClient using npm or yarn
Source: https://resgate.io/docs/writing-clients/resclient
Instructions for installing the ResClient library using package managers like npm or yarn. This is the recommended way to include ResClient in your project.
```bash
npm install resclient --save
```
```bash
yarn add resclient
```
--------------------------------
### Grant Full Access to Resources with Wildcard Subscription
Source: https://resgate.io/docs/writing-services/03serving-resources
This example demonstrates how to grant full access (GET and CALL) to a set of resources using a wildcard subscription pattern for access requests. The response grants 'get: true' and 'call: "*"'.
```nats
nats.subscribe('access.example.>', (msg, reply) => {
nats.publish(reply, JSON.stringify({ result: { get: true, call: "*" }}));
});
```
--------------------------------
### Respond to GET Request with a Collection
Source: https://resgate.io/docs/writing-services/03serving-resources
This example demonstrates how to respond to a GET request for a collection. The response is published to the 'reply' subject and must contain a 'result.collection' property with an array of data.
```nats
nats.subscribe('get.example.bar', (msg, reply) => {
nats.publish(reply, JSON.stringify({
result: {
collection: [ 12, "bar", null ]
}
}));
});
```
--------------------------------
### Get Request Result Example (Model)
Source: https://resgate.io/docs/specification/res-service-protocol
This example illustrates the result of a get request when the resource is represented as a model. The 'model' member contains an object with the named properties and values of the resource. This is mutually exclusive with the 'collection' member.
```json
{
"model": {
"propertyName": "value"
},
"query": "normalized/query"
}
```
--------------------------------
### Login Auth Request Example
Source: https://resgate.io/docs/writing-services/07access-control
A practical example demonstrating a login authentication flow using NATS publish and subscribe.
```APIDOC
## Login Auth Request Example
### Description
An example demonstrating a complete login authentication process. It subscribes to a specific NATS topic for login requests, validates credentials, and publishes a token event or an error response.
### Method
NATS Subscribe/Publish
### Endpoint
`auth.authexample.login` (Subscription Topic)
### Parameters
#### Request Body (from NATS message)
- **params** (object) - Contains login credentials (e.g., `user`, `pass`).
- **cid** (string) - The connection ID of the client making the request.
### Request Example (NATS Message Payload)
```json
{
"params": { "user": "admin", "pass": "secret" },
"cid": "some-connection-id"
}
```
### Response (Published to `reply` topic)
#### Success Response
- **result** (null) - Indicates successful authentication.
#### Error Response
- **error** (object) - Contains error details.
- **code** (string) - Specific error code (e.g., `example.loginFailed`).
- **message** (string) - Human-readable error message.
### Code Example (NATS Handler)
```javascript
nats.subscribe('auth.authexample.login', (msg, reply) => {
let { params, cid } = JSON.parse(msg);
// We use hardcoded login parameters for the example
if (params && params.user == "admin" && params.pass == "secret") {
// Set a token
nats.publish("conn." + cid + ".token", JSON.stringify({
"token": { "loggedIn": true }
}));
// Send successful response
nats.publish(reply, JSON.stringify({
"result": null
}));
} else {
// Send an custom error response
nats.publish(reply, JSON.stringify({
error: {
code: "example.loginFailed",
message: "Invalid username or password"
}
}));
}
});
```
```
--------------------------------
### Get Request Result Example (Collection)
Source: https://resgate.io/docs/specification/res-service-protocol
This example shows the result of a get request when the resource is represented as a collection. The 'collection' member is an ordered array containing the values of the resource. This is mutually exclusive with the 'model' member.
```json
{
"collection": [
"value1",
"value2"
],
"query": "normalized/query"
}
```
--------------------------------
### Installing NATS and Running NodeJS Service
Source: https://resgate.io/docs/writing-services/01hello-world
These commands are used to set up and run the NodeJS 'Hello World' service for Resgate. First, it installs the 'nats' library using npm, and then it executes the service script using Node.js. Ensure NATS Server and Resgate are running prior to execution.
```bash
npm install nats
node hello-world.js
```
--------------------------------
### Run Resgate with Default Settings
Source: https://resgate.io/docs/get-started/installation
This command starts the Resgate server using its default configuration. It assumes that a NATS server is already installed and running, typically on TCP port 4222. Upon successful startup, Resgate will connect to NATS and begin listening on HTTP port 8080.
```bash
resgate
```
--------------------------------
### Resource Set Example (JSON)
Source: https://resgate.io/docs/specification/res-client-protocol
An example of a resource set, grouped by type (models, collections, errors), as sent in requests or events. This structure helps clients manage subscribed resources efficiently.
```json
{
"models": {
"messageService.message.1": {
"id": 1,
"msg": "foo"
},
"messageService.message.2": {
"id": 2,
"msg": "bar"
}
},
"collections": {
"messageService.messages": [
{ "rid": "messageService.message.1" },
{ "rid": "messageService.message.2" },
{ "rid": "messageService.message.3" }
]
},
"errors": {
"messageService.message.3": {
"code": "system.notFound",
"message": "Not found"
}
}
}
```
--------------------------------
### Wildcard Subscriptions for GET Requests
Source: https://resgate.io/docs/writing-services/03serving-resources
Demonstrates the use of wildcard subscriptions for handling GET requests where resource IDs might include parameters. This allows for more flexible resource addressing.
```APIDOC
## GET /inventory/item/{itemId}
### Description
Handles GET requests for inventory items using a wildcard subscription.
### Method
GET
### Endpoint
`get.inventory.item.*`
### Parameters
#### Query Parameters
- **query** (string) - Optional - The query part of the resource ID.
### Request Example
```json
{
"query": "optional_query_string"
}
```
### Response
#### Success Response (200)
- **result** (object) - Contains the inventory item data.
- **model** (object) - The inventory item details.
#### Response Example
```json
{
"result": {
"model": {
"itemId": "some_id",
"name": "Example Item",
"price": 19.99
}
}
}
```
```
--------------------------------
### Initializing ResClient Instance
Source: https://resgate.io/docs/writing-clients/using-modapp
Provides a simple example of how to create an instance of ResClient, which is required to interact with Resgate for fetching data. The constructor takes the WebSocket URL of the Resgate server as an argument.
```javascript
let client = new ResClient('ws://localhost:8080');
```
--------------------------------
### Example Result Payload with Events (JSON)
Source: https://resgate.io/docs/specification/res-service-protocol
This JSON object shows an example of a result payload containing an 'events' array. Each object in the array represents an event to be applied to the query resource, such as 'remove' or 'add'.
```json
{
"events": [
{ "event": "remove", "data": { "idx": 24 }},
{ "event": "add", "data": { "value": "foo", "idx": 0 }}
]
}
```
--------------------------------
### Login Authentication Request Example with NATS
Source: https://resgate.io/docs/writing-services/07access-control
Provides a NATS subscription example for handling a login authentication request. It parses the incoming message, validates credentials, publishes a connection token event upon success, and sends a response (either success or custom error) back to the client.
```javascript
nats.subscribe('auth.authexample.login', (msg, reply) => {
let { params, cid } = JSON.parse(msg);
// We use hardcoded login parameters for the example
if (params && params.user == "admin" && params.pass == "secret") {
// Set a token
nats.publish("conn." + cid + ".token", JSON.stringify({
"token": { "loggedIn": true }
}));
// Send successful response
nats.publish(reply, JSON.stringify({
"result": null
}));
} else {
// Send an custom error response
nats.publish(reply, JSON.stringify({
error: {
code: "example.loginFailed",
message: "Invalid username or password"
}
}));
}
});
```
--------------------------------
### RES Protocol: Collection Example (JSON)
Source: https://resgate.io/docs/specification/res-protocol
An example of a 'collection' resource in the RES protocol, represented as a JSON array. This structure defines an ordered list of values, which can include other resources.
```json
[ "admin", "tester", "developer" ]
```
--------------------------------
### RES Protocol: Model Example (JSON)
Source: https://resgate.io/docs/specification/res-protocol
An example of a 'model' resource in the RES protocol, represented as a JSON object with named properties and values. This structure defines a single resource instance.
```json
{
"id": 42,
"name": "Jane Doe",
"roles": { "rid": "example.user.42.roles" }
}
```
--------------------------------
### Access Control for Resources
Source: https://resgate.io/docs/writing-services/03serving-resources
This section explains how to set up access control for resources using wildcard subscriptions. It demonstrates granting full GET and CALL access to all resources under a specific domain.
```APIDOC
## Access Control
### Description
Grants access control permissions for resources.
### Method
ACCESS
### Endpoint
`access.example.>`
### Parameters
No specific parameters for this subscription, but the message payload defines permissions.
### Request Example
(This is a subscription setup, not a direct request)
```javascript
nats.subscribe('access.example.>', (msg, reply) => {
nats.publish(reply, JSON.stringify({ result: { get: true, call: "*" }}));
});
```
### Response
#### Success Response (200)
- **result** (object) - Access permissions.
- **get** (boolean) - Whether GET requests are allowed.
- **call** (string) - Allowed call patterns (e.g., "*" for all).
#### Response Example
```json
{
"result": {
"get": true,
"call": "*"
}
}
```
```
--------------------------------
### Subscribe to All Access Requests with Wildcard (NATS)
Source: https://resgate.io/docs/writing-services/07access-control
This example shows how to use a wildcard ('access.example.>') to subscribe to all access requests for resources within a specific domain. This allows a single handler to manage access control for multiple resources.
```javascript
nats.subscribe('access.example.>', (msg, reply, subject) => {
/* Authorize and send a response based on token and subject */
});
```
--------------------------------
### Access Request Payload Example
Source: https://resgate.io/docs/specification/res-service-protocol
An example of the payload structure for an access request. It includes the client connection ID (cid), an optional access token, the query part of the resource ID, and a flag indicating if the response meta object can include HTTP status and headers.
```json
{
"cid": "connection-id-123",
"token": "optional-access-token",
"query": "some/resource/query",
"isHttp": true
}
```
--------------------------------
### Pre-response Timeout Example
Source: https://resgate.io/docs/specification/res-service-protocol
This snippet demonstrates how a service might send a pre-response to set a new request timeout. The 'timeout' key specifies the new timeout in milliseconds from the perspective of the requester receiving the pre-response. This is useful when a request might exceed the default timeout.
```text
timeout:"15000"
```
--------------------------------
### Model Example in JSON
Source: https://resgate.io/docs/writing-services/02basic-concepts
Demonstrates the structure of a 'model' resource in Resgate, which is an unordered key/value JSON object. Values must be JSON primitives.
```json
{
"id": 42,
"name": "Jane Doe",
"isAdmin": true
}
```
--------------------------------
### Get and Display Resources in Vue.js
Source: https://resgate.io/docs/writing-clients/using-vuejs
Shows how to fetch resources (like a list of books) using ResClient's 'get' method in the 'created' hook and store them in Vue.js component data. The fetched data is then passed as a prop to a child component.
```javascript
data: {
this.books = null
},
created() {
this.client = new ResClient('ws://localhost:8080');
this.client.get('library.books').then(books => {
this.books = books;
});
}
```
--------------------------------
### Collection Example in JSON
Source: https://resgate.io/docs/writing-services/02basic-concepts
Illustrates a 'collection' resource, represented as an ordered JSON array. Collections can contain JSON primitives of mixed types.
```json
[ 12, "foo", null ]
```
--------------------------------
### Fetching a Resource with ResClient
Source: https://resgate.io/docs/writing-clients/using-modapp
Demonstrates how to use the `get` method of a ResClient instance to fetch a specific resource from Resgate. The method returns a Promise that resolves with the requested resource data. This is a fundamental step before rendering data.
```javascript
client.get('library.books').then(books => {
/* Rendering of book list */
});
```
--------------------------------
### Session Data Structure Example
Source: https://resgate.io/docs/advanced-topics/client-sessions
An example of a session data object that a service might store. It includes a unique session ID (sid), the client's connection ID (cid), user information, and creation timestamp.
```json
{
sid: "a3JsHylu6iLPbeCnqK9wBDb5XZ8jz4Ua",
cid: "bi17lut8smgihf37loa0",
user: { id: 42, username: "foo", name: "Foo Bar" role: "guest" },
created: "2006-01-02T15:04:05Z"
}
```
--------------------------------
### Example Access Request Handler with Role Check (NATS)
Source: https://resgate.io/docs/writing-services/07access-control
This comprehensive example demonstrates an access request handler that checks the client's token for a specific role ('admin'). It grants full access if the role matches, otherwise it denies all access.
```javascript
nats.subscribe('access.example.foo', (msg, reply) => {
let { token } = JSON.parse(msg);
// Verify we have a token (it may be null) and that the role is "admin"
if (token && token.role == "admin") {
// Grant full access
nats.publish(reply, JSON.stringify({ result: { get: true, call: "*" }}});
} else {
// Deny all access
nats.publish(reply, JSON.stringify({ result: { get: false }}});
}
});
```
--------------------------------
### Query Resource Handling
Source: https://resgate.io/docs/advanced-topics/query-resources
Demonstrates how to handle a GET request for a query resource using NATS subscriptions and process query parameters.
```APIDOC
## GET /inventory.items?category=toys&start=0&limit=25
### Description
Handles GET requests for inventory items with filtering, pagination, and sorting capabilities, returning real-time updated results.
### Method
GET
### Endpoint
`/inventory.items?category={category}&start={start}&limit={limit}`
### Parameters
#### Query Parameters
- **category** (string) - Optional - Filters items by category.
- **start** (integer) - Optional - The starting index for pagination. Defaults to 0.
- **limit** (integer) - Optional - The maximum number of items to return. Defaults to 25.
### Request Example
```javascript
// Using ResClient
client.get('inventory.items?category=toys&start=0&limit=25').then(itemList => { /* ... */ });
// Using REST requests
GET http://localhost:8080/api/inventory/items?category=toys&start=0&limit=25
```
### Response
#### Success Response (200)
- **result** (object) - Contains the collection of items and a normalized query string.
- **collection** (array) - The list of inventory items matching the query.
- **query** (string) - A normalized and predictable representation of the query parameters used.
#### Response Example
```json
{
"result": {
"collection": [
{
"id": "item1",
"name": "Toy Car",
"category": "toys",
"stock": 10
}
],
"query": "category=toys&start=0&limit=25"
}
}
```
### NATS Subscription Example
```javascript
nats.subscribe('get.inventory.items', (req, reply) => {
let { query } = JSON.parse(req);
// Parse and validate query parameters (e.g., start, limit, category)
let parsedQuery = parseQuery(query);
let collection = getInventoryCollection(parsedQuery.start, parsedQuery.limit, parsedQuery.category);
nats.publish(reply, JSON.stringify({
result: {
collection,
// Normalize the query in a predictable order
query: "category=" + parsedQuery.category + "&start=" + parsedQuery.start + "&limit=" + parsedQuery.limit
}
}));
});
function parseQuery(query) {
const url = require('url');
let q = query ? url.parse('?' + query, true).query : {};
let start = q.start ? parseInt(q.start, 10) : 0;
let limit = q.limit ? parseInt(q.limit, 10) : 0;
let category = q.category || "";
// Add validation logic here
return { start, limit, category };
}
```
### Notes
- If a service ignores the query entirely, it is considered a non-query resource, and no `query` string should be included in the response.
- Query normalization is recommended for performance and consistency, allowing Resgate to identify equivalent queries.
```
--------------------------------
### Change Event Object Example
Source: https://resgate.io/docs/specification/res-client-protocol
Demonstrates the structure of a change event object, which includes properties that have been modified or deleted. Unchanged properties may be present but should be ignored.
```json
{
"event": "myService.myModel.change",
"data": {
"myProperty": "New value",
"unusedProperty": { "action": "delete" }
}
}
```
--------------------------------
### Example Query Request Payload (JSON)
Source: https://resgate.io/docs/specification/res-service-protocol
This JSON object demonstrates the structure of a query request payload sent in response to a query event. It includes the 'query' parameter, which specifies filtering and sorting criteria.
```json
{
"query": "limit=25&start=0"
}
```
--------------------------------
### Generate Default Configuration File
Source: https://resgate.io/docs/get-started/configuration
A new configuration file with default settings can be generated by using the `--config` option with a non-existent file path. This is a convenient way to start customizing Resgate's configuration.
```bash
resgate --config myconfig.json
```
--------------------------------
### Collection Add Event Object Example
Source: https://resgate.io/docs/specification/res-client-protocol
Illustrates the structure of an add event object for collections. It includes the index of insertion, the added value, and optional resource set models, collections, and errors.
```json
{
"event": "userService.users.add",
"data": {
"idx": 12,
"value": { "rid": "userService.user.42" },
"models": {
"userService.user.42": {
"id": 42,
"firstName": "Jane",
"lastName": "Doe"
}
}
}
}
```
--------------------------------
### Accessing Hello World Resource with ResClient
Source: https://resgate.io/docs/writing-services/01hello-world
This Javascript code snippet shows how to access the 'example.model' resource served by the Resgate 'Hello World' service using ResClient. It retrieves the model and logs the 'message' property to the console. This assumes ResClient is available and connected.
```javascript
client.get('example.model').then(model => {
console.log(model.message);
});
```
--------------------------------
### NodeJS Hello World Service for Resgate
Source: https://resgate.io/docs/writing-services/01hello-world
This NodeJS code snippet demonstrates a basic 'Hello World' service for Resgate. It connects to NATS, subscribes to 'get.example.model' to serve resource data, and 'access.example.model' to grant GET access. It uses the 'nats' library.
```javascript
const nats = require('nats').connect('nats://localhost:4222');
nats.subscribe('get.example.model', (req, reply) => {
nats.publish(reply, JSON.stringify({ result: { model: { message: "Hello, World!" }}}));
});
nats.subscribe('access.example.model', (req, reply) => {
nats.publish(reply, JSON.stringify({ result: { get: true }}}));
});
```
--------------------------------
### Example Access Response Denying Get Access (NATS)
Source: https://resgate.io/docs/writing-services/07access-control
This code snippet shows how to deny a client's request to get a resource by sending an access response with 'get' set to false. Other methods might still be callable if specified.
```javascript
nats.publish(reply, JSON.stringify({ result: { get: false }}));
```
--------------------------------
### Example Access Response Granting Full Access (NATS)
Source: https://resgate.io/docs/writing-services/07access-control
This code illustrates how to send an access response from a service back to Resgate. It grants the client full access (both get and call) by setting 'get' to true and 'call' to '*'.
```javascript
nats.publish(reply, JSON.stringify({ result: { get: true, call: "*" }}));
```
--------------------------------
### Listening on the Client
Source: https://resgate.io/docs/advanced-topics/connection-resources
Demonstrates how a client can retrieve the user info model and listen for 'change' events to track the login status in real-time.
```APIDOC
## Client-side Usage
### Description
Shows how to fetch the user model on the client and subscribe to its changes to display login status.
### Method
GET and LISTEN
### Endpoint
`session.user.{cid}`
### Parameters
#### Path Parameters
- **cid** (string) - Required - The connection ID tag.
### Request Example
```javascript
client.get('session.user.{cid}').then(user => {
let showUserStatus = () => {
if (user.id) {
console.log("Logged in as " + user.name);
} else {
console.log("Logged out");
}
};
user.on('change', showUserStatus);
showUserStatus();
});
```
### Response
(The 'user' object returned by `client.get` will have properties like `id`, `name`, `role` and an `on` method for event listening.)
```
--------------------------------
### Handle Token Revocation and Publish System Token Reset (NATS)
Source: https://resgate.io/docs/advanced-topics/token-update
This example shows how to set up an NATS subscription to handle authentication requests for token revocation. It parses the incoming message to get the connection ID, then publishes a null token to the connection's token subject to revoke access. It also demonstrates publishing a 'system.tokenReset' event to trigger this revocation for a specific token ID.
```javascript
// Auth request handler for clearing/revoking tokens.
nats.subscribe('auth.authservice.logout', (msg, reply) => {
// Parse out the connection ID (cid).
let { cid } = JSON.parse(msg);
// Clear the token for this connection.
nats.publish("conn." + cid + ".token", JSON.stringify({
"token": null
}));
// Send successful response.
// Resgate discards results from system.tokenReset auth requests.
nats.publish(reply, JSON.stringify({
"result": null
}));
});
// Send system.tokenReset event to update/clear the token of user 42
nats.publish("system.tokenReset", JSON.stringify({
"tids": [ "42" ],
"subject": "auth.authservice.logout"
}));
```
--------------------------------
### Loading Modapp and ResClient Dependencies via UMD
Source: https://resgate.io/docs/writing-clients/using-modapp
Demonstrates how to load necessary JavaScript libraries (ResClient, modapp-base-component, modapp-resource-component) using UMD bundles in HTML script tags. This approach simplifies dependency management for examples by making constructors available in the global scope.
```html
```
--------------------------------
### Respond to GET Request with an Error
Source: https://resgate.io/docs/writing-services/03serving-resources
This code snippet shows how to send an error response to a GET request. The response is published to the 'reply' subject and includes an 'error' object with 'code' and 'message' properties.
```nats
{
"error": {
"code": "system.notFound",
"message": "Not Found"
}
}
```
--------------------------------
### Respond to GET Request with a Model
Source: https://resgate.io/docs/writing-services/03serving-resources
This code illustrates how to respond to a GET request for a model. The response is published back to the 'reply' subject and must follow the specified JSON structure with a 'result.model' property.
```nats
nats.subscribe('get.example.foo', (req, reply) => {
nats.publish(reply, JSON.stringify({
result: {
model: { foo: "baz", bar: 42 }
}
}));
});
```
--------------------------------
### Subscribe to GET Requests for a Specific Resource
Source: https://resgate.io/docs/writing-services/03serving-resources
This code snippet demonstrates how a service subscribes to NATS subjects to listen for GET requests for a specific resource ID. The subject pattern is 'get.'.
```nats
nats.subscribe('get.example.foo', (msg, reply) => { /* ... */ });
```
--------------------------------
### Connect to Resgate using ResClient
Source: https://resgate.io/docs/writing-clients/resclient
Demonstrates how to establish a connection to Resgate using the ResClient library. It requires the WebSocket URL of the Resgate instance.
```javascript
let client = new ResClient('ws://localhost:8080');
```
--------------------------------
### Initialize ResClient in React Component
Source: https://resgate.io/docs/writing-clients/using-react
Demonstrates how to create a ResClient instance within the constructor of a React component. This sets up the client for communication with the Resgate server.
```javascript
class App extends Component {
constructor(props) {
super(props);
this.state = { books: null };
this.client = new ResClient("ws://127.0.0.1:8080");
}
/* ... */
}
```
--------------------------------
### Handling GET Requests
Source: https://resgate.io/docs/writing-services/03serving-resources
This section details how to handle GET requests in Resgate. Services subscribe to subjects matching 'get.' to receive these requests. The request message may contain an optional 'query' property.
```APIDOC
## GET /resources/{resource}
### Description
Handles GET requests for a specific resource.
### Method
GET
### Endpoint
`get.`
### Parameters
#### Query Parameters
- **query** (string) - Optional - The query part of the resource ID.
### Request Example
```json
{
"query": "optional_query_string"
}
```
### Response
#### Success Response (200)
- **result** (object) - Contains the resource data.
- **model** (object) - If the resource is a model.
- **collection** (array) - If the resource is a collection.
#### Error Response (e.g., 404)
- **error** (object) - Contains error details.
- **code** (string) - The error code (e.g., "system.notFound").
- **message** (string) - A human-readable error message.
#### Response Example (Model)
```json
{
"result": {
"model": {
"foo": "baz",
"bar": 42
}
}
}
```
#### Response Example (Collection)
```json
{
"result": {
"collection": [
12,
"bar",
null
]
}
}
```
#### Response Example (Error)
```json
{
"error": {
"code": "system.notFound",
"message": "Not Found"
}
}
```
```
--------------------------------
### Serving Connection Resources
Source: https://resgate.io/docs/advanced-topics/connection-resources
This section explains how services can subscribe to requests for connection-specific resources, using a wildcard subscription and the connection ID tag. It also shows how to validate access based on the connection ID.
```APIDOC
## GET /session/user/{cid}
### Description
Retrieves connection-specific user information using the connection ID tag.
### Method
GET
### Endpoint
`/session/user/{cid}`
### Parameters
#### Path Parameters
- **cid** (string) - Required - The connection ID tag, which Resgate replaces with the actual connection ID.
### Request Example
```
client.get('session.user.{cid}');
```
### Response
#### Success Response (200)
- **model** (object) - An object containing user information (id, name, role) or null values if the connection is not logged in.
- **id** (string|null) - The user's ID.
- **name** (string|null) - The user's name.
- **role** (string|null) - The user's role.
#### Response Example
```json
{
"result": {
"model": {
"id": "user123",
"name": "John Doe",
"role": "admin"
}
}
}
```
## SUBSCRIBE access.session.user.*
### Description
Handles access control for connection-specific resources by validating the connection ID.
### Method
SUBSCRIBE
### Endpoint
`access.session.user.*`
### Parameters
#### Request Body
- **cid** (string) - The connection ID of the requester.
### Response
#### Success Response (200)
- **result** (object)
- **get** (boolean) - True if the connection ID matches the resource's connection ID, false otherwise.
#### Response Example
```json
{
"result": {
"get": true
}
}
```
```
--------------------------------
### Client-side Listening to User Model Changes
Source: https://resgate.io/docs/advanced-topics/connection-resources
Explains how a client can retrieve the user model and subscribe to 'change' events to receive real-time updates on the user's login status and information.
```javascript
client.get('session.user.{cid}').then(user => {
let showUserStatus = () => {
if (user.id) {
console.log("Logged in as " + user.name);
} else {
console.log("Logged out");
}
};
model.on('change', showUserStatus);
showUserStatus();
});
```
--------------------------------
### RES Protocol: Value Examples (JSON)
Source: https://resgate.io/docs/specification/res-protocol
Illustrates various types of 'values' within the RES protocol, including primitives (string, number, boolean, null), resource references, and data values. Data values can encapsulate any JSON, offering flexibility.
```json
"foo" // string
42 // number
true // boolean true
false // boolean false
null // null
{ "rid": "example.user.42" } // resource reference
{ "rid": "example.page.2", "soft":true } // soft reference
{ "data": { "foo": [ "bar" ] }} // data value
{ "data": 42 } // data value interchangeable with the primitive 42
```
--------------------------------
### Delete Event
Source: https://resgate.io/docs/specification/res-service-protocol
Sent when a resource is considered deleted, invalidating previous get responses.
```APIDOC
## Delete event
### Subject
`event..delete`
### Description
Delete events are sent when the resource is considered deleted. It will invalidate any previous get response received for the resource.
The event has no payload.
```
--------------------------------
### Publishing User Model Change Events (Login)
Source: https://resgate.io/docs/advanced-topics/connection-resources
Demonstrates how to publish a 'change' event to update the user info model when a user logs in. The event includes the updated user details.
```javascript
nats.publish('event.session.user.' + cid + '.change', JSON.stringify({
values: { id: user.id, name: user.name, role: user.role }
}));
```
--------------------------------
### Get Request API
Source: https://resgate.io/docs/specification/res-service-protocol
Retrieves the JSON representation of a resource, supporting optional query parameters.
```APIDOC
## Get Request
**Subject**: `get.`
Get requests are sent to get the JSON representation of a resource.
### Parameters
#### Request Payload
- **query** (string) - Optional - Query part of the resource ID without the question mark separator. MUST be omitted if the resource ID has no query.
### Result
- **model** (object) - Optional - An object containing the named properties and values of the model. MUST be omitted if `collection` is provided.
- **collection** (array) - Optional - An ordered array containing the values of the collection. MUST be omitted if `model` is provided.
- **query** (string) - Optional - Normalized query without the question mark separator. Different queries (eg. `a=1&b=2` and `b=2&a=1`) that results in the same query resource should have the same normalized query (eg. `a=1&b=2`). The normalized query will be used by the gateway in query requests, and in get requests triggered by a system reset event. MAY be included even if the request had no `query` parameter. MUST be omitted if the resource is not a query resource. MUST NOT be omitted if the resource is a query resource.
### Error Handling
Any error response will be treated as if the resource is currently unavailable. A `system.notFound` error SHOULD be sent if the resource ID doesn’t exist. A `system.invalidQuery` error SHOULD be sent if the query is malformed or invalid.
```
--------------------------------
### Get Request
Source: https://resgate.io/docs/specification/res-client-protocol
Fetches a resource directly without establishing a subscription.
```APIDOC
## Get Request
Get requests are sent by the client to get a resource without making a subscription.
**method**
`get.`
### Parameters
The request has no parameters.
```
--------------------------------
### Publish Message in NATS
Source: https://resgate.io/docs/writing-services/02basic-concepts
Example of publishing a message to a specific subject using the NATS messaging system. This is a fundamental operation for inter-service communication.
```javascript
nats.publish('my.subject', "Hello world");
```