From 45d4f34e91091c1fe4024117c5811fbacd499cf6 Mon Sep 17 00:00:00 2001 From: Adrien Maret Date: Wed, 5 Jun 2019 11:13:58 +0200 Subject: [PATCH] Rewrite the Realtime guide (#296) Rewrite the guide about the real-time engine --- .gitignore | 1 + .../1/api/essentials/notifications/index.md | 6 +- .../1/api/essentials/volatile-data/index.md | 4 +- .../1/guides/essentials/real-time/index.md | 509 +++++++++++++++--- .../1/guides/essentials/real-time/pub-sub.png | Bin 0 -> 31572 bytes .../real-time/snippets/subscribe-filter.js | 23 - .../snippets/subscribe-filter.test.yml | 14 - .../real-time/snippets/subscribe-no-filter.js | 21 - .../snippets/subscribe-no-filter.test.yml | 14 - .../real-time/snippets/subscribe-options.js | 26 - .../snippets/subscribe-options.test.yml | 14 - .../real-time/subscription-filter-scope.png | Bin 0 -> 18615 bytes .../realtime-notifications/index.md | 4 +- .../realtime-notifications/index.md | 2 +- .../realtime-notifications/index.md | 4 +- .../realtime-notifications/index.md | 4 +- 16 files changed, 438 insertions(+), 208 deletions(-) create mode 100644 src/core/1/guides/essentials/real-time/pub-sub.png delete mode 100644 src/core/1/guides/essentials/real-time/snippets/subscribe-filter.js delete mode 100644 src/core/1/guides/essentials/real-time/snippets/subscribe-filter.test.yml delete mode 100644 src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.js delete mode 100644 src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.test.yml delete mode 100644 src/core/1/guides/essentials/real-time/snippets/subscribe-options.js delete mode 100644 src/core/1/guides/essentials/real-time/snippets/subscribe-options.test.yml create mode 100644 src/core/1/guides/essentials/real-time/subscription-filter-scope.png diff --git a/.gitignore b/.gitignore index 37204f675..3438e8600 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ test/bin/* dead_links.json links_failed.json .links_checked.json +.vscode diff --git a/src/core/1/api/essentials/notifications/index.md b/src/core/1/api/essentials/notifications/index.md index 337226d8a..65a4f3bec 100644 --- a/src/core/1/api/essentials/notifications/index.md +++ b/src/core/1/api/essentials/notifications/index.md @@ -83,9 +83,9 @@ The `result` object is the notification content, and it has the following struct --- -## User events +## User Notification -User notifications about users are triggered by the following events: +User notifications are triggered by the following events: - A user subscribes to the same room - A user leaves that room @@ -138,7 +138,7 @@ The `result` object is the notification content, and it has the following struct --- -## Server events +## Server Notification Server notifications are triggered by global events, and they are sent to all of a client's subscriptions at the same time. diff --git a/src/core/1/api/essentials/volatile-data/index.md b/src/core/1/api/essentials/volatile-data/index.md index 1e275467b..695c5fd74 100644 --- a/src/core/1/api/essentials/volatile-data/index.md +++ b/src/core/1/api/essentials/volatile-data/index.md @@ -76,8 +76,8 @@ There is one special case, where volatile data are stored by Kuzzle for a later Volatile data passed to a new subscription query are used two times by Kuzzle: -- if the new subscription triggers [user notifications](/core/1/api/essentials/notifications#user-events-default), its volatile data are included into those -- if that subscription is cancelled, whether because of a call to [realtime:unsubscribe](/core/1/api/controllers/realtime/unsubscribe/), or after the user disconnects: the volatile data provided **at the time of the subscription** are once again copied into user notifications triggered by that event +- if the new subscription triggers [user notifications](/core/1/api/essentials/notifications#user-notification-default), its volatile data are included into those +- if that subscription is cancelled, whether because of a call to [realtime:unsubscribe](/core/1/api/api-reference/controller-realtime/unsubscribe/), or after the user disconnects: the volatile data provided **at the time of the subscription** are once again copied into user notifications triggered by that event This allows other real-time subscribers to get context information about a user joining or leaving the same subscription as them. diff --git a/src/core/1/guides/essentials/real-time/index.md b/src/core/1/guides/essentials/real-time/index.md index d1f8d99ef..7d4a1db55 100644 --- a/src/core/1/guides/essentials/real-time/index.md +++ b/src/core/1/guides/essentials/real-time/index.md @@ -1,152 +1,493 @@ --- code: false type: page -title: Real-time Notifications +title: Real-time Engine order: 600 --- -# Real-time Notifications +# Real-time Engine -Kuzzle features highly customizable notifications thanks to its **real-time engine** which lets you configure live subscriptions to any dataset. These live subscriptions are a great way to **track** changes in specific subsets of data. +Kuzzle includes his own real-time engine for sending notifications to clients connected through the API. ---- +Real-time capabilities requires the use of a persistent communication protocol such as WebSocket or MQTT. -## Introduction +Kuzzle offers 2 different ways of doing real-time: + - volatile Pub/Sub system + - real-time database notifications -Imagine you are developing a collaborative TO-DO application like [this](https://github.com/kuzzleio/demo/tree/master/todolist) one. All the TO-DO items are persisted in Kuzzle (in a collection called `todos`) so, once clients start, they fetch every available TO-DO items via a simple document search. + ::: info +You can bypass notifications from being triggered by using actions from the [bulk controller](/core/1/api/controllers/bulk). +::: -But imagine that one of the users (let's call her Ann), adds a new TO-DO item. In order for other users (let's call them Tom and Matt) to display these new item, they need to perform a new document search on the corresponding collection. They will not see the new items until they refresh (or restart) their application. -This cannot be called a "modern" application: it rather looks like an old-school, refresh-ish, one. Like the early '90s. Today, such a user-experience wouldn't be satisfying at all. +### wscat -A more interesting user-experience would be that clients display the new TO-DO item _as soon as it is created_. How can we achieve that? +This guide provides examples that use the Kuzzle API directly through a command line WebSocket client: [wscat](https://github.com/websockets/wscat). -- By implementing a long-polling mechanism in the clients. Every, say, one second, the clients perform a document search and update their list of TO-DO items. Doesn't look like a great idea (performances would be rather bad, for example) -- By providing notifications to subscribed clients, allowing them to receive these new items automatically, as soon as they are saved in the system +To install it you can type the following command: `npm install -g wscat`. -The second solution is exactly what we are looking for and Kuzzle ships it natively. We can call it **pub/sub**, **notifications** or **live subscriptions** and it is often used to solve use-cases like this one, where things need to be kept _in sync_ between clients and the back-end server. +The sample requests are to be sent directly to wscat after connecting to your Kuzzle server with the command `wscat --connect localhost:7512`. -Getting back to our example, our collaborative TO-DO list clients only need to subscribe to the TO-DO collection (right after the first document search), in order to be notified _in real-time_ about new TO-DO items. This way, once Ann creates her new item, Tom and Matt can see it immediately on their screen. +It is of course possible to send the payloads provided with a different WebSocket client than wscat. ---- +## Pub/Sub -## Concepts +Kuzzle's real-time engine allows you to do Pub/Sub in dedicated communication channels called rooms. -Real-time notifications are triggered by the [pub/sub mechanism](https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern) embedded in Kuzzle and follow the [Observer/Observable pattern](https://en.wikipedia.org/wiki/Observer_pattern), in which Kuzzle is the Observable and the client is the Observer. +The process is as follows: + - a customer subscribes to a particular room, + - a second customer posts a message in this room, + - the customer subscribing to the room receives a notification. -They are is possible only when the communication happens in a **persistent-connection**-oriented protocol (like Websockets or MQTT) and therefore not with HTTP. +![kuzzle-pub-sub](./pub-sub.png) -Clients can subscribe to many types of notifications. Below are some examples: +Subscription to a room is done via the [realtime:subscribe](/core/1/api/controllers/realtime/subscribe) method. It takes 3 parameters, used to describe a specific room: + - name of an index, + - name of a collection, + - subscription filters contained in the `body` of the request. -1. **new documents** being created in a given collection (e.g. Ann creates a new TO-DO item); -2. **documents being deleted** from a given collection (e.g. Tom deletes a TO-DO item); -3. **changes happening** on any document within a collection (e.g. Matt checks an item as "done"); -4. **changes happening on a given set of documents** (e.g. clients must play a sound every time an item containing the word "URGENT" is created). +::: info +In order to use Kuzzle in Pub/Sub mode only, the index and collection do not need to physically exist in the database (e.g. created in Kuzzle via the index:create and collection:create methods of the API). +
+These information are only used to define an ephemeral room between several customers. +::: -The scope of possibilities is huge. Take a look at the [Notifications section](/core/1/api/essentials/notifications) in the API Reference for more details. +```json + { + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + // subscription filters + } + } +``` ---- +Payload to send with wscat: +```json +{"controller":"realtime","action":"subscribe","index":"nyc-open-data","collection":"yellow-taxi","body":{}} +``` -## Examples +Then clients wishing to post messages in this room must use the [realtime:publish](/core/1/api/controllers/realtime/publish) method by specifying the same parameters: -But, how does this work in Kuzzle? **How do we select the data that we want to subscribe to?** +```json + { + "controller": "realtime", + "action": "publish", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + "name": "Manwë", + "licence": "B", + "car": "berline", + "position": { + "lat": 43.6073913, + "lon": 3.9109057 + } + } + } +``` -Let's dive into the implementation of the Collaborative TO-DO list application. +Payload to send with wscat in another terminal: +```json +{"controller":"realtime","action":"publish","index":"nyc-open-data","collection":"yellow-taxi","body":{"name":"Manwë","licence":"B","car":"berline","position":{"lat":43.6073913,"lon":3.9109057}}} +``` -
-All the following examples are written in Javascript, therefore using the Javascript Kuzzle SDK. If this is not your usual development language, take a look at the different flavors of the `subscribe` method in the [/sdk/js/5/core-classes/collection/subscribe](SDK Reference)). -
+Customers subscribing to this channel will receive the following notification: ---- +
Click to expand +
+{
+  "status": 200,
+  "requestId": "644bc890-9c14-4a8f-afcc-afef444fd6f7",
+  "timestamp": 1558690506519,
+  "volatile": null,
+  "index": "nyc-open-data",
+  "collection": "yellow-taxi",
+  "controller": "realtime",  // Controller who trigger the notification
+  "action": "publish",       // Action who trigger the notification
+  "protocol": "websocket",
+  "scope": "in",
+  "result": {
+    "_source": {
+      // Content of the published document
+      "name": "Manwë",
+      "licence": "B",
+      "car": "berline",
+      "position": {
+        "lat": 43.6073913,
+        "lon": 3.9109057
+      },
+      "_kuzzle_info": {
+        "author": "-1",
+        "createdAt": 1558690506527
+      }
+    },
+    "_id": null
+  },
+  "type": "document", // Notification is of type document
+  "room": "54ffaa49fe470879bed9b0697468bb21-89c22fbf000567a2ed2e7886ed0c51e3"
+}
+
+
-### The basic subscription +More information about the [Document Notification format](/core/1/api/essentials/notifications/#documents-changes-messages) -Once our client has started and initialized with the set of TO-DO items it fetched from the persistence layer, we want it to subscribe to the changes happening on them. +::: warning +Messages published with the realtime:publish method are not persisted in the database. +::: -<<< ./snippets/subscribe-no-filter.js +## Database notifications -This code isn't very useful at the moment, but it shows the capability to react to a notification coming from the server. +Kuzzle's real-time engine allows you to subscribe to notifications corresponding to changes in the database. -Here, we call the `subscribe` method: +Subscription to a database changes is done via the [realtime:subscribe](/core/1/api/controllers/realtime/subscribe) method, taking 3 parameters: + - name of the index, + - name of the collection you want to watch, + - subscription filters contained in the `body` of the request. -- The first argument is the index. -- The second argument is the collection we want to subscribe to. -- The third argument represents the _filters_, and in this case there's none, which means that we are subscribing to _all documents changes_ in the collection. Filters enable more fine-grained selection on the data we want to subscribe to and are described in the next example. -- The fourth argument is the _callback_, i.e. a function that is called _every time a notification is received_. +::: info +The specified index and collection must exist in the database to receive database notifications. +::: -Now, imagine this code is executed on Tom's client: when Ann creates the new TO-DO item, Tom receives a notification looking like the following: +When changes occur on this collection (eg: document creation, modification or deletion), Kuzzle will send notifications to the corresponding subscribers. + +```json + { + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + // subscription filters + } + } +``` + +Payload to send with wscat: +```json +{"controller":"realtime","action":"subscribe","index":"nyc-open-data","collection":"yellow-taxi","body":{}} +``` + +For example, creating a document with the [document:create](/core/1/api/controllers/document/create) method corresponds to a change in the database, so customers subscribing to notifications in this collection will be notified. ```json { - "status": 200, - "type": "document", - "index": "todo-list", - "collection": "todos", "controller": "document", "action": "create", - "state": "done", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + "name": "Morgoth", + "car": "limousine", + "licence": "B" + } +} +``` + +
Payload to send with wscat in another terminal +
+{"controller":"document","action":"create","index":"nyc-open-data","collection":"yellow-taxi","body":{"name":"Morgoth","licence":"B","car":"limousine"}}
+
+
+ +Customers subscribing to the changes in this collection will receive the following notification: + +
Click to expand +
+{
+  "status": 200,
+  "requestId": "556e8499-8edc-488c-ab7c-2f6aa9d12acd",
+  "timestamp": 1558781280054,
+  "volatile": null,
+  "index": "nyc-open-data",
+  "collection": "yellow-taxi",
+  "controller": "document",  // Controller who trigger the notification
+  "action": "create",        // Action who trigger the notification
+  "protocol": "websocket",
   "scope": "in",
-  "volatile": {},
-  "requestId": "",
   "result": {
-    "_id": "",
     "_source": {
-      "label": "The new item Ann just created!",
-      "checked": "false"
+      // Content of the created document
+      "name": "Morgoth",
+      "licence": "B",
+      "car": "limousine",
+      "_kuzzle_info": {
+        "author": "-1",
+        "createdAt": 1558781280058,
+        "updatedAt": null,
+        "updater": null,
+        "active": true,
+        "deletedAt": null
+      }
     },
-    "_meta": {
-      "author": "ann",
-      "createdAt": 1497866996975,
-      "updatedAt": null,
-      "updater": null,
-      "active": true,
-      "deletedAt": null
-    }
+    "_id": "AWrumr8-njeq4FJZaOmC"
+  },
+  "type": "document",  // Notification is of type document
+  "room": "54ffaa49fe470879bed9b0697468bb21-89c22fbf000567a2ed2e7886ed0c51e3"
+}
+```
+
+
+ +More information about the [Document Notification format](/core/1/api/essentials/notifications/#documents-changes-messages) + +## Subscription filters + +When a customer subscribes to real-time notifications, whether in Pub/Sub or Database Notification, he can specify a set of subscription filters. +These filters allow the customer to tell Kuzzle exactly which documents they are interested in and only receive notifications about them. + +::: info +These filters are specified only on the client side and do not require server-side implementation. +They are sent in the body of the request [realtime:subscribe](/core/1/api/controllers/realtime/subscribe) +::: + +A filter is composed of [term](/core/1/koncorde/essentials/terms) that can be composed with [operands](/core/1/koncorde/essentials/operands). + +For example if I want to receive only drivers with the `B` license: +```json +{ + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + "equals": { "licence": "B" } } } ``` -The Notification bears some useful information about what just happened: +It is also possible to combine [terms](/core/1/koncorde/essentials/terms) between them with [operands](/core/1/koncorde/essentials/operands) to refine my filter: -- the `controller` and `action` attributes show _what_ has happened; -- the `index` and `collection` attributes show _where_ it happened; -- the `result` shows _the consequence_ of what just happened (in this case, the newly created document). +```json +{ + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + "and": [ + { "equals": { "licence": "B" } }, + { "equals": { "car": "berline" } } + ] + } +} +``` -We won't analyze the other attributes for the moment. Take a look at the [Notifications section of the API Reference](/core/1/api/essentials/notifications) for a comprehensive list of available notification properties. +Each subscription filter defines a scope. All documents in the collection can be either inside or outside this scope. -This subscription is very handy and will notify Tom about the events 1, 2 and 3 of the list above (the `controller`, `action` and `result` will vary depending on the case). But what about the event number 4? How does Tom subscribe to items that only contain the word `URGENT` in their `label` field? Looks like a job for [Koncorde](/core/1/koncorde/). +Once a customer has subscribed to notifications with filters, they will receive notifications each time a document enters or exits the scope defined by the filters. ---- +![subscription-filter-scope](./subscription-filter-scope.png) -### Subscription with filters +This information is contained in the `scope` field of the notifications: -Kuzzle ships with a powerful filtering tool named [Koncorde](/core/1/koncorde/). It enables you to perform fine-grained selections on the documents you want to subscribe to. +
Click to expand +
+{
+  "status": 200,
+  "requestId": "556e8499-8edc-488c-ab7c-2f6aa9d12acd",
+  "timestamp": 1558781280054,
+  "volatile": null,
+  "index": "nyc-open-data",
+  "collection": "yellow-taxi",
+  "controller": "document",
+  "action": "create",
+  "protocol": "websocket",
+  "scope": "in",           // Notification about a document entering the scope
+  "result": {
+    "_source": {
+      "name": "Manwë",
+      "licence": "B",
+      "car": "berline",
+      "_kuzzle_info": {
+        "author": "-1",
+        "createdAt": 1558781280058,
+        "updatedAt": null,
+        "updater": null,
+        "active": true,
+        "deletedAt": null
+      }
+    },
+    "_id": "AWrumr8-njeq4FJZaOmC"
+  },
+  "type": "document",
+  "room": "54ffaa49fe470879bed9b0697468bb21-89c22fbf000567a2ed2e7886ed0c51e3"
+}
+
+
-In our case, we want to select all the documents that contain the `URGENT` word in the `label` field. The best pick for this case is the [regexp](/core/1/koncorde/essentials/terms/#regexp-default) filter. +## Subscription options -<<< ./snippets/subscribe-filter.js +In addition to filters, it is possible to specify options to the [realtime:subscribe](/core/1/api/controllers/realtime/subscribe) method to refine the notifications received or add context information to the notifications that will be sent. -This way, Tom will be notified about urgent TO-DO items. Take a look at the [Koncorde Reference](/core/1/koncorde/) for a comprehensive list of available filters. +### scope -There are a few things that deserve to be noticed here: +The [scope](/core/1/api/controllers/realtime/subscribe/#arguments) option allows you to specify whether you want to receive notifications regarding documents entering or leaving the scope only. -- Tom will be notified either if somebody creates, updates or deletes a document containing the word `URGENT`; -- Tom will be notified even if he performs the actions himself (e.g. he is notified right after having created a new TO-DO item). +This parameter can take 3 values: + - `in`: receive only notifications about documents entering the scope + - `out`: receive only notifications about documents exiting the scope + - `all`: (default) receive everything -The last point may seem a little bit inconvenient. What if Tom does not want to receive notifications when the event come from his own actions? Keep reading, the solution is right below. +For example, to be informed of taxis arriving at central park: +```json +{ + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + "geoBoundingBox": { + "position": { + "topLeft": { "lat": 40.759507, "lon": -73.985384 }, + "bottomRight": { "lat": 40.758372, "lon": -73.984591 } + } + } + }, + "scope": "in" // Only documents entering the scope +} +``` ---- +### users -### Subscription with options +The [users](/core/1/api/controllers/realtime/subscribe/#arguments) option allows you to receive additional notifications when another client joins or leaves the same room. + +This parameter can take 4 values: + - `in`: only receive notifications when a customer joins the room + - `out`: only receive notifications when a customer leaves the room + - `all`: receive everything + - `none`: (default) receive nothing + +```json + { + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + }, + "user": "all" // Receive notification when a user enters or exits the room + } +``` + +Payload to send with wscat: +```json +{"controller":"realtime","action":"subscribe","index":"nyc-open-data","collection":"yellow-taxi","body":{},"users":"all"} +``` + +If a second customer subscribes to the same notifications, then the customer will receive the following notification: + +
Click to expand +
+{
+  "status": 200,
+  "timestamp": 1558792881867,
+  "volatile": null,
+  "index": "nyc-open-data",
+  "collection": "yellow-taxi",
+  "controller": "realtime",
+  "action": "subscribe",
+  "protocol": "websocket",
+  "user": "in",   // User entering the room
+  "result": {
+    "count": 2    // Users subscribed to the room
+  },
+  "type": "user", // Notification about a user
+  "room": "54ffaa49fe470879bed9b0697468bb21-24f5ac19056dbab464867c9515f8dbc5"
+}
+
+
-The `subscribe` method can be called with an extra argument, which is an object containing a set of options to be passed to the subscription Room. +More information about the [User Notification format](/core/1/api/essentials/notifications/#user-notification) -We just introduced a new concept here, the Room. A Room is a class representing a single subscription and its constructor is called internally by the `subscribe` method. -This object supports a wide range of options that can be passed directly to its [constructor](/sdk/js/5/core-classes/room/), allowing to configure the kind of notifications we want to receive. +### volatile data + +[Volatile data](/core/1/api/essentials/volatile-data/) are metadata that can be added to each request made to the Kuzzle API. + +When a request containing volatile data triggers a real-time notification, these volatile data are included in the notification that will be sent to the subscribing customers. + +For example, if a customer subscribes to the following notifications: + +```json + { + "controller": "realtime", + "action": "subscribe", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + // subscription filters + } + } +``` + +Payload to send with wscat: +```json +{"controller":"realtime","action":"subscribe","index":"nyc-open-data","collection":"yellow-taxi","body":{}} +``` + +If another client publishes a message in the room specifying volatile data: + +```json + { + "controller": "realtime", + "action": "publish", + "index": "nyc-open-data", + "collection": "yellow-taxi", + "body": { + "name": "Ulmo", + "licence": "B" + }, + "volatile": { + "senderName": "Eru Ilúvatar" + } + } +``` + +Payload to send with wscat in another terminal: +```json +{"controller":"realtime","action":"publish","index":"nyc-open-data","collection":"yellow-taxi","body":{"name":"Manwë","licence":"B","car":"berline","position":{"lat":43.6073913,"lon":3.9109057}},"volatile":{"senderName":"Eru Ilúvatar"}} +``` + +Each customer who subscribes to the room will receive the following notification: + +
Click to expand +
+{
+  "status": 200,
+  "requestId": "644bc890-9c14-4a8f-afcc-afef444fd6f7",
+  "timestamp": 1558690506519,
+  "volatile": {
+     "senderName": "Eru Ilúvatar" // Volatile data included in the notification
+   },
+  "index": "nyc-open-data",
+  "collection": "yellow-taxi",
+  "controller": "realtime",
+  "action": "publish",
+  "protocol": "websocket",
+  "scope": "in",
+  "result": {
+    "_source": {
+      "name": "Ulmo",
+      "licence": "B",
+      "_kuzzle_info": {
+        "author": "-1",
+        "createdAt": 1558690506527
+      }
+    },
+    "_id": null
+  },
+  "type": "document",
+  "room": "54ffaa49fe470879bed9b0697468bb21-89c22fbf000567a2ed2e7886ed0c51e3"
+}
+
+
-For now, let's concentrate on the question asked at the end of the previous chapter: how do we filter the notifications resulting of our own actions? -The option we are looking for is `subscribeToSelf`, which is set to `true` by default. +## Where do we go from here? -<<< ./snippets/subscribe-options.js +Now that you're more familiar with Kuzzle, dive even deeper to learn how to leverage its full capabilities: -In the code right above, we added the extra "options" object as the fifth argument to avoid subscribing Tom to his own events. +- take a look at the available [SDKs](/sdk) +- learn how to use [Koncorde](/core/1/koncorde/essentials/introduction/) to create fine-grained subscription filters +- follow our guide to learn how to [manage users and setup fine-grained access control](/core/1/guides/essentials/security/) diff --git a/src/core/1/guides/essentials/real-time/pub-sub.png b/src/core/1/guides/essentials/real-time/pub-sub.png new file mode 100644 index 0000000000000000000000000000000000000000..81a250061ac5fa4e9ba04188f01f5e6cff0249fb GIT binary patch literal 31572 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 literal 0 HcmV?d00001 diff --git a/src/core/1/guides/essentials/real-time/snippets/subscribe-filter.js b/src/core/1/guides/essentials/real-time/snippets/subscribe-filter.js deleted file mode 100644 index 5632fe249..000000000 --- a/src/core/1/guides/essentials/real-time/snippets/subscribe-filter.js +++ /dev/null @@ -1,23 +0,0 @@ -// Create a filter that defines a regexp -const filter = {regexp: {label: 'URGENT'}}; -// Triggered whenever a document matching the filter is submitted to Kuzzle -const callback = (error, notification) => { - if (error) { - throw new Error(error); - } - console.log( - 'Something happened and we should do something URGENTLY.', - notification - ); -}; -try { - await kuzzle.realtime.subscribe( - 'todo-list', - 'todos', - filter, - callback - ); - console.log('subscribe ok'); -} catch (error) { - console.error(error.message); -} \ No newline at end of file diff --git a/src/core/1/guides/essentials/real-time/snippets/subscribe-filter.test.yml b/src/core/1/guides/essentials/real-time/snippets/subscribe-filter.test.yml deleted file mode 100644 index 0b35fcb27..000000000 --- a/src/core/1/guides/essentials/real-time/snippets/subscribe-filter.test.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: real-time-notifications#subscribe-filter -description: subscribe collection with filter -hooks: - before: | - curl -XPOST kuzzle:7512/todo-list/_create - curl -XPUT kuzzle:7512/todo-list/todos - after: | - curl -XDELETE kuzzle:7512/todo-list -template: default -expected: subscribe ok - -sdk: js -version: 6 \ No newline at end of file diff --git a/src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.js b/src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.js deleted file mode 100644 index 56eb07e27..000000000 --- a/src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.js +++ /dev/null @@ -1,21 +0,0 @@ -// Triggered whenever a document matching the filter is submitted to Kuzzle -const callback = (error, notification) => { - if (error) { - throw new Error(error); - } - console.log( - 'Something happened and we should do something.', - notification - ); -}; -try { - await kuzzle.realtime.subscribe( - 'todo-list', - 'todos', - {}, - callback - ); - console.log('subscribe ok'); -} catch (error) { - console.error(error.message); -} \ No newline at end of file diff --git a/src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.test.yml b/src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.test.yml deleted file mode 100644 index 05bedd6ea..000000000 --- a/src/core/1/guides/essentials/real-time/snippets/subscribe-no-filter.test.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: real-time-notifications#subscribe-no-filter -description: subscribe collection no filter -hooks: - before: | - curl -XPOST kuzzle:7512/todo-list/_create - curl -XPUT kuzzle:7512/todo-list/todos - after: | - curl -XDELETE kuzzle:7512/todo-list -template: default -expected: subscribe ok - -sdk: js -version: 6 \ No newline at end of file diff --git a/src/core/1/guides/essentials/real-time/snippets/subscribe-options.js b/src/core/1/guides/essentials/real-time/snippets/subscribe-options.js deleted file mode 100644 index dbc208feb..000000000 --- a/src/core/1/guides/essentials/real-time/snippets/subscribe-options.js +++ /dev/null @@ -1,26 +0,0 @@ -// Create a filter that defines a regexp -const filter = {regexp: {label: 'URGENT'}}; -// The Options object -const options = {subscribeToSelf: false}; -// Triggered whenever a document matching the filter is submitted to Kuzzle -const callback = (error, notification) => { - if (error) { - throw new Error(error); - } - console.log( - 'Something happened and we should do something URGENTLY.', - notification - ); -}; -try { - await kuzzle.realtime.subscribe( - 'toto-list', - 'todos', - filter, - callback, - options - ); - console.log('subscribe ok'); -} catch (error) { - console.error(error.message); -} \ No newline at end of file diff --git a/src/core/1/guides/essentials/real-time/snippets/subscribe-options.test.yml b/src/core/1/guides/essentials/real-time/snippets/subscribe-options.test.yml deleted file mode 100644 index c4940259b..000000000 --- a/src/core/1/guides/essentials/real-time/snippets/subscribe-options.test.yml +++ /dev/null @@ -1,14 +0,0 @@ ---- -name: real-time-notifications#subscribe-options -description: subscribe collection with options -hooks: - before: | - curl -XPOST kuzzle:7512/todo-list/_create - curl -XPUT kuzzle:7512/todo-list/todos - after: | - curl -XDELETE kuzzle:7512/todo-list -template: default -expected: subscribe ok - -sdk: js -version: 6 \ No newline at end of file diff --git a/src/core/1/guides/essentials/real-time/subscription-filter-scope.png b/src/core/1/guides/essentials/real-time/subscription-filter-scope.png new file mode 100644 index 0000000000000000000000000000000000000000..93bbc05da2a4b5d5f1c15543e189d21f35210918 GIT binary patch literal 18615 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 literal 0 HcmV?d00001 diff --git a/src/sdk/cpp/1/essentials/realtime-notifications/index.md b/src/sdk/cpp/1/essentials/realtime-notifications/index.md index a6e771591..6af6485f8 100644 --- a/src/sdk/cpp/1/essentials/realtime-notifications/index.md +++ b/src/sdk/cpp/1/essentials/realtime-notifications/index.md @@ -8,7 +8,7 @@ order: 100 # Notifications -The [realtime:subscribe](/sdk/cpp/1/controllers/realtime/) method takes a listener of type `kuzzleio::NotificationListener`. +The [realtime:subscribe](/sdk/cpp/1/controllers/realtime/) method takes a listener of type `kuzzleio::NotificationListener`. That listener is called with a `const kuzzleio::notification_result*` argument, pointing to an object whose content depends on the type of notification received. ## Document & messages @@ -38,7 +38,7 @@ The `kuzzleio::notification_content` struct has the following properties for doc ## User -These `kuzzleio::notification_result` represent [user events](/core/1/api/essentials/notifications#user-events-default). +These `kuzzleio::notification_result` represent [user events](/core/1/api/essentials/notifications#user-notification-default). | Property | Type | Description | | ------------ | ------------------------------------------- | ----------------------------------------------------------------------------------------------------- | diff --git a/src/sdk/go/1/essentials/realtime-notifications/index.md b/src/sdk/go/1/essentials/realtime-notifications/index.md index 141bdcceb..040c2f31a 100644 --- a/src/sdk/go/1/essentials/realtime-notifications/index.md +++ b/src/sdk/go/1/essentials/realtime-notifications/index.md @@ -37,7 +37,7 @@ The `Result` property has the following structure for document notifications & m ## User -These notifications represent [user events](/core/1/api/essentials/notifications#user-events-default). +These notifications represent [user events](/core/1/api/essentials/notifications#user-notification-default). | Property | Type | Description | | ------------ | -------------------------- | ----------------------------------------------------------------------------------------------------- | diff --git a/src/sdk/java/1/essentials/realtime-notifications/index.md b/src/sdk/java/1/essentials/realtime-notifications/index.md index 0783ee2a2..50410818f 100644 --- a/src/sdk/java/1/essentials/realtime-notifications/index.md +++ b/src/sdk/java/1/essentials/realtime-notifications/index.md @@ -8,7 +8,7 @@ order: 100 # Notifications -The [Realtime.subscribe](/sdk/java/1/controllers/realtime/subscribe/) method takes a `io.kuzzle.sdk.NotificationListener` event listener (implements the `EventListener` interface). +The [Realtime.subscribe](/sdk/java/1/controllers/realtime/subscribe/) method takes a `io.kuzzle.sdk.NotificationListener` event listener (implements the `EventListener` interface). That listener is fed with a `io.kuzzle.sdk.NotificationResult` object, whose content depends on the type of notification. Properties can be accessed with usual getters and setters. @@ -40,7 +40,7 @@ The `io.kuzzle.sdk.NotificationContent` object has the following properties for ## User -These `io.kuzzle.sdk.NotificationResult` represent [user events](/core/1/api/essentials/notifications#user-events-default). +These `io.kuzzle.sdk.NotificationResult` represent [user events](/core/1/api/essentials/notifications#user-notification-default). | Property | Type | Description | | ------------ | --------------------------------- | ----------------------------------------------------------------------------------------------------- | diff --git a/src/sdk/js/6/essentials/realtime-notifications/index.md b/src/sdk/js/6/essentials/realtime-notifications/index.md index 45d570203..af0384e0e 100644 --- a/src/sdk/js/6/essentials/realtime-notifications/index.md +++ b/src/sdk/js/6/essentials/realtime-notifications/index.md @@ -37,7 +37,7 @@ The `result` object is the notification content, and it has the following struct ## User -These notifications represent [user events](/core/1/api/essentials/notifications#user-events-default). +These notifications represent [user events](/core/1/api/essentials/notifications#user-notification-default). | Property | Type | Description | | ------------ | ----------------- | ----------------------------------------------------------------------------------------------------- | @@ -61,7 +61,7 @@ The `result` object is the notification content, and it has the following struct ## Server -These notifications represent [server events](/core/1/api/essentials/notifications#server-events-default). +These notifications represent [server events](/core/1/api/essentials/notifications#server-notification-default). | Property | Type | Value | | --------- | ----------------- | ------------------------------------------------------------------ |