### 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"); ```