docs: refactor streaming subscription docs

PR-URL: https://github.com/hasura/graphql-engine-mono/pull/4350
Co-authored-by: Rikin Kachhia <54616969+rikinsk@users.noreply.github.com>
GitOrigin-RevId: 230263a5c3446a6761e000dcef4994237a720df9
This commit is contained in:
Karthikeyan Chinnakonda 2022-04-26 12:49:57 +05:30 committed by hasura-bot
parent 9bbc802f27
commit 5b95599b54
7 changed files with 212 additions and 106 deletions

View File

@ -18,21 +18,6 @@ an update whenever the value of any field changes upstream.
Subscriptions are supported for all kinds of queries. All the concepts Subscriptions are supported for all kinds of queries. All the concepts
of [queries](/graphql/core/databases/postgres/queries/index.mdx) hold true for subscriptions as well. of [queries](/graphql/core/databases/postgres/queries/index.mdx) hold true for subscriptions as well.
## Implementation
The Hasura GraphQL engine subscriptions are actually **live queries**,
i.e. a subscription will return the latest result of the query being
made and not necessarily all the individual events leading up to the
result. By default, updates are delivered to clients every **1 sec**.
See more details on
`subscriptions execution and performance [subscriptions execution and performance](/graphql/core/databases/postgres/subscriptions/execution-and-performance.mdx).
## Convert a query to a subscription
You can turn any query into a subscription by simply replacing `query`
with `subscription` as the operation type.
:::info Caveat :::info Caveat
Hasura follows the [GraphQL spec](https://graphql.github.io/graphql-spec/June2018/#sec-Single-root-field) Hasura follows the [GraphQL spec](https://graphql.github.io/graphql-spec/June2018/#sec-Single-root-field)
@ -40,11 +25,84 @@ which allows for only one root field in a subscription.
::: :::
## Use cases ## Types of subscriptions
- [Subscribe to the latest value of a particular field](/graphql/core/databases/postgres/subscriptions/use-cases.mdx#pg-subscribe-field) ### Live queries
- [Subscribe to changes to a tables entries](/graphql/core/databases/postgres/subscriptions/use-cases.mdx#pg-subscribe-table)
- [Subscribe to the latest value of some derived data](/graphql/core/databases/postgres/subscriptions/use-cases.mdx#pg-subscribe-derived)
A live query subscription will return the latest result of the query being made
and not necessarily all the individual events leading up to the result.
By default, updates are delivered to clients every **1 sec**.
See more details [here](/graphql/core/databases/postgres/subscriptions/livequery/index.mdx).
### Streaming subscriptions
A streaming subscription streams the response according to the cursor input
by the user. A streaming subscription is different from a live query as it sends individual rows
at a time and not the entire result set.
See more details [here](/graphql/core/databases/postgres/subscriptions/streaming/index.mdx).
### Live query vs Streaming subscriptions
Suppose we need to display the messages of a group chat on a page, this can be done either via
live queries or streaming subscriptions. Let's see how they can be used and how they differ from each other.
1. Using **live query**
With live query, we'll make the following query:
```graphql
subscription {
messages (
where: {group_id: 1},
order_by: {created_at: asc}
) {
id
sender
reciever
content
created_at
edited_at
}
}
```
The initial response for this subscription will be all the messages of the group. Let's say the initial
response contained 100 messages. Now, if there is one more message sent to the group, then all 101 messages
will be sent in a new response.
2. Using **streaming subscriptions**
With streaming subscriptions, we'll make the following query:
```graphql
subscription {
messages_stream (
where: {group_id: 1},
cursor: {initial_value: {created_at: now}},
batch_size: 10
) {
id
sender
reciever
content
created_at
edited_at
}
}
```
Here, we'll start getting all messages of the group in batches given by ``batch_size`` with ``created_at``
greater than ``now``.
Following the example of the live query, if we have 100 messages corresponding to the group and only
5 messages with ``created_at`` greater than the current value of the cursor maintained by the cursor, then
we will get only the 5 messages.
## Communication protocol ## Communication protocol

View File

@ -0,0 +1,40 @@
---
description: Manage subscriptions on Postgres with Hasura
sidebar_label: Live queries
keywords:
- hasura
- docs
- postgres
- subscription
- live queries
slug: index
---
# Postgres: Live query subscriptions
## Introduction
A Live query subscription will return the latest result of the query being made
and not necessarily all the individual events leading up to the result.
By default, updates are delivered to clients every **1 sec**.
See more details on [subscriptions execution and performance](/graphql/core/databases/postgres/subscriptions/livequery/execution-and-performance.mdx).
## Convert a query to a subscription
You can turn any query into a subscription by simply replacing `query`
with `subscription` as the operation type.
:::info Caveat
Hasura follows the [GraphQL spec](https://graphql.github.io/graphql-spec/June2018/#sec-Single-root-field)
which allows for only one root field in a subscription.
:::
## Use cases
- [Subscribe to the latest value of a particular field](/graphql/core/databases/postgres/subscriptions/livequery/use-cases.mdx#pg-subscribe-field)
- [Subscribe to changes to a tables entries](/graphql/core/databases/postgres/subscriptions/livequery/use-cases.mdx#pg-subscribe-table)
- [Subscribe to the latest value of some derived data](/graphql/core/databases/postgres/subscriptions/livequery/use-cases.mdx#pg-subscribe-derived)

View File

@ -11,11 +11,11 @@ keywords:
import GraphiQLIDE from '@site/src/components/GraphiQLIDE'; import GraphiQLIDE from '@site/src/components/GraphiQLIDE';
# Subscriptions sample use cases # Live query subscriptions sample use cases
## Introduction ## Introduction
The following are a few use cases for using subscriptions: The following are a few use cases for using live query subscriptions:
## Subscribe to the latest value of a particular field {#pg-subscribe-field} ## Subscribe to the latest value of a particular field {#pg-subscribe-field}
@ -84,7 +84,7 @@ variables={`{
In case you are interested in all the additions/changes to a table's In case you are interested in all the additions/changes to a table's
entries, you can use subscriptions to fetch the table rows and get entries, you can use subscriptions to fetch the table rows and get
updates whenever there are any additions/changes to the table. live query updates whenever there are any additions/changes to the table.
### Example: Chat app ### Example: Chat app
@ -227,7 +227,7 @@ subscription getResult($pollId: Int!) {
) { ) {
poll_id poll_id
poll { poll {
question question
} }
option { option {
texts texts
@ -278,7 +278,7 @@ response={`{
}, },
"option": { "option": {
"texts": "Burger" "texts": "Burger"
}, },
"votes": 3 "votes": 3
}, },
{ {

View File

@ -1,58 +1,49 @@
.. meta:: ---
:description: Streaming subscriptions with Hasura description: Streaming subscriptions with Hasura
:keywords: hasura, docs, subscription, streaming sidebar_label: Streaming subscriptions
keywords:
- hasura
- docs
- subscription
- streaming
- postgres
slug: index
---
.. _pg_streaming_subscriptions: # Postgres: Streaming subscriptions
Postgres: Streaming subscriptions ## Introduction
=================================
.. contents:: Table of contents
:backlinks: none
:depth: 1
:local:
Introduction
------------
A streaming subscription streams the response according to the cursor provided A streaming subscription streams the response according to the cursor provided
by the user while making the subscription. Streaming subscriptions can be used to by the user while making the subscription. Streaming subscriptions can be used to
subscribe only to the data which has been newly added to the result set. subscribe only to the data which has been newly added to the result set.
.. admonition:: Supported from :::tip Supported from
Streaming subscriptions are supported in Hasura GraphQL engine versions ``v2.5.0-beta.1`` and above. Streaming subscriptions are supported in Hasura GraphQL engine versions ``v2.7.0-beta.1`` and above.
.. admonition:: Enabling streaming subscriptions :::tip Enabling streaming subscriptions
Streaming subscriptions in the graphql-engine are disabled by default. To enable it, Streaming subscriptions in the graphql-engine are disabled by default. To enable it,
set the environment variable ``HASURA_GRAPHQL_EXPERIMENTAL_FEATURES`` to ``streaming_subscriptions``. set the environment variable ``HASURA_GRAPHQL_EXPERIMENTAL_FEATURES`` to ``streaming_subscriptions``.
How it works? ## How it works?
-------------
In streaming subscriptions, the server maintains a cursor value with a subscription and In streaming subscriptions, the server maintains a cursor value with a subscription and
after streaming each batch, the value of the cursor is updated. Ideally, the cursor chosen after streaming each batch, the value of the cursor is updated. Ideally, the cursor chosen
should represent unique and sortable values so that each row is sent exactly once to a subscriber. should represent unique and sortable values so that each row is sent exactly once to a subscriber.
Streaming subscriptions work well with other Hasura features like Streaming subscriptions work well with other Hasura features like
:ref:`permissions <permission_rules>` and :ref:`relationships <pg_table_relationships>` and also [permissions](/graphql/core/auth/authorization/permission-rules.mdx#select-permissions) and [relationships](/graphql/core/databases/postgres/schema/table-relationships/index.mdx#table-relationships) and also
leverage the power of :ref:`multiplexing <subscription_multiplexing>`. leverage the power of
[subscriptions multiplexing](/graphql/core/databases/postgres/subscriptions/livequery/execution-and-performance.mdx#subscription-multiplexing).
.. note:: :::info Note
In the case of streaming subscriptions, the multiplexed batch size can be configured via In the case of streaming subscriptions, the multiplexed batch size can be configured via
``HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_BATCH_SIZE`` and the refetch interval can be ``HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_BATCH_SIZE`` and the refetch interval can be
configured via ``HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_REFETCH_INTERVAL``. configured via ``HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_REFETCH_INTERVAL``.
Use cases ## Use cases
---------
- :ref:`pg_streaming_subscriptions_use_cases` - [Subscribe to the undelivered messages in a chat application](/graphql/core/databases/postgres/subscriptions/streaming/use-cases.mdx)
.. toctree::
:maxdepth: 1
:hidden:
Sample use cases <use-cases>

View File

@ -1,39 +1,32 @@
.. meta:: ---
:description: Use cases for Hasura streaming subscriptions description: Use cases for Hasura streaming subscriptions
:keywords: hasura, docs, subscription, use case, streaming sidebar_label: Sample use cases
sidebar_position: 1
keywords:
- hasura
- docs
- subscription
- streaming
- use cases
- postgres
---
.. _pg_streaming_subscriptions_use_cases: # Streaming subscriptions sample use cases
Streaming subscriptions sample use cases ## Introduction
========================================
.. contents:: Table of contents
:backlinks: none
:depth: 1
:local:
Introduction
------------
The following are a few use cases for using streaming subscriptions: The following are a few use cases for using streaming subscriptions:
.. _pg_streaming_changed_events: ### Subscribing only to the events that have been changed
Subscribing only to the events that have been changed
-----------------------------------------------------
In case you are interested only in the latest events, you can use streaming subscriptions In case you are interested only in the latest events, you can use streaming subscriptions
to fetch those events. to fetch those events.
.. _pg_get_undelivered_messages: ### Get the undelivered messages in a chat application
Get the undelivered messages in a chat application
--------------------------------------------------
Consider the following schema: Consider the following schema:
.. code-block:: sql ```sql
messages ( messages (
id serial primary key, id serial primary key,
from_id uuid references users(id), from_id uuid references users(id),
@ -49,11 +42,11 @@ Consider the following schema:
last_name text, last_name text,
created_at timestamptz default current_timestamp created_at timestamptz default current_timestamp
) )
```
and the following messages need to be streamed: and the following messages need to be streamed:
.. code-block:: json ```json
[ [
{ {
"id": 432432, "id": 432432,
@ -100,11 +93,11 @@ and the following messages need to be streamed:
"created_at": "2020-01-01 01:01:20" "created_at": "2020-01-01 01:01:20"
} }
] ]
```
To stream the latest undelivered messages: To stream the latest undelivered messages:
.. code-block:: graphql ```graphql
subscription getUndeliveredMessages { subscription getUndeliveredMessages {
# will get all the messages that have `created_at > 2022-01-01` in batches of 100 rows # will get all the messages that have `created_at > 2022-01-01` in batches of 100 rows
messages_stream(cursor: {created_at: "2022-01-01", ordering: ASC}, batch_size: 2) { messages_stream(cursor: {created_at: "2022-01-01", ordering: ASC}, batch_size: 2) {
@ -119,11 +112,11 @@ To stream the latest undelivered messages:
created_at created_at
} }
} }
```
The first response sent will be: The first response sent will be:
.. code-block:: json ```json
{ {
"data": { "data": {
"messages_stream": [ "messages_stream": [
@ -152,12 +145,13 @@ The first response sent will be:
] ]
} }
} }
```
The next response sent will be the following, note that the messages sent The next response sent will be the following, note that the messages sent
have ``created_at > 2020-01-01 01:01:20``, the greatest value of the cursor have ``created_at > 2020-01-01 01:01:20``, the greatest value of the cursor
column sent in the previous response. column sent in the previous response.
.. code-block:: json ```json
{ {
"data": { "data": {
@ -187,7 +181,4 @@ column sent in the previous response.
] ]
} }
} }
```
.. toctree::
:maxdepth: 1
:hidden:

View File

@ -223,7 +223,7 @@ Enable the Hasura Console (served by the server on `/` and `/console`) (default:
</td> </td>
<td> <td>
A JSON string containing type and the JWK used for verifying (and other optional details). Example: A JSON string containing type and the JWK used for verifying (and other optional details). Example:
`{"type": "HS256", "key": "3bd561c37d214b4496d09049fadc542c"}`. See the JWT docs for more details. `{"type": "HS256", "key": "3bd561c37d214b4496d09049fadc542c"}`. See the JWT docs for more details.
</td> </td>
@ -242,9 +242,9 @@ A JSON string containing type and the JWK used for verifying (and other optional
</td> </td>
<td> <td>
Unauthorized role, used when access-key is not sent in access-key only mode or the Unauthorized role, used when access-key is not sent in access-key only mode or the
`Authorization` header is absent in JWT mode. Example: `anonymous`. Now whenever the `Authorization` header is absent in JWT mode. Example: `anonymous`. Now whenever the
"authorization" header is absent, the request's role will default to "authorization" header is absent, the request's role will default to
`anonymous`. `anonymous`.
</td> </td>
@ -358,7 +358,7 @@ Maximum number of events to be fetched from the DB in a single batch (default: 1
</td> </td>
<td> <td>
Interval in milliseconds to sleep before trying to fetch async actions again after a fetch returned no async actions from metadata storage. Value Interval in milliseconds to sleep before trying to fetch async actions again after a fetch returned no async actions from metadata storage. Value
`0` implies completely disable fetching async actions from the storage. `0` implies completely disable fetching async actions from the storage.
<em>(Available for versions > v2.0.0)</em> <em>(Available for versions > v2.0.0)</em>
@ -505,7 +505,7 @@ Time from connection creation after which the connection should be destroyed and
</td> </td>
<td> <td>
Stringify certain Postgres numeric types, specifically Stringify certain Postgres numeric types, specifically
`bigint` ,`numeric` ,`decimal` and `double precision` as they don't fit into the `IEEE-754` `bigint` ,`numeric` ,`decimal` and `double precision` as they don't fit into the `IEEE-754`
spec for JSON encoding-decoding. (default: false) spec for JSON encoding-decoding. (default: false)
@ -558,6 +558,32 @@ Comma separated list of APIs (options: `metadata`, `graphql`, `pgdump`, `config`
<tr> <tr>
<td> <td>
`--streaming-queries-multiplexed-refetch-interval`
</td>
<td>
`HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_REFETCH_INTERVAL`
</td>
<td>Updated results (if any) will be sent at most once in this interval (in milliseconds) for streaming queries which can be multiplexed. Default: 1000 (1sec)</td>
</tr>
<tr>
<td>
`--streaming-queries-multiplexed-batch-size`
</td>
<td>
`HASURA_GRAPHQL_STREAMING_QUERIES_MULTIPLEXED_BATCH_SIZE`
</td>
<td>Multiplexed streaming queries are split into batches of the specified size. Default: 100</td>
</tr>
<tr>
<td>
`--enable-allowlist` `--enable-allowlist`
</td> </td>
@ -603,7 +629,7 @@ Set the value to `/srv/console-assets` for the console to load assets from the s
</td> </td>
<td> <td>
Set the enabled log types. This is a comma-separated list of log-types to enable. Default: Set the enabled log types. This is a comma-separated list of log-types to enable. Default:
`startup, http-log, webhook-log, websocket-log`. `startup, http-log, webhook-log, websocket-log`.
See [log types](/graphql/core/deployment/logging.mdx#log-types) for more details. See [log types](/graphql/core/deployment/logging.mdx#log-types) for more details.
@ -639,7 +665,7 @@ Set the logging level. Default: `info`. Options: `debug`, `info`, `warn`, `error
</td> </td>
<td> <td>
Set dev mode for GraphQL requests; include the Set dev mode for GraphQL requests; include the
`internal` key in the errors extensions of the response (if required). `internal` key in the errors extensions of the response (if required).
<em>(Available for versions > v1.2.0)</em> <em>(Available for versions > v1.2.0)</em>
@ -696,7 +722,7 @@ Enable remote schema permissions (default: `false`)
</td> </td>
<td> <td>
When the `--infer-function-permissions` flag is set to `false`, a function `f`, stable, immutable or volatile is only exposed for a role When the `--infer-function-permissions` flag is set to `false`, a function `f`, stable, immutable or volatile is only exposed for a role
`r` if there is a permission defined on the function `f` for the role `r`, creating a function permission will only be allowed if there is a select permission on the table type. `r` if there is a permission defined on the function `f` for the role `r`, creating a function permission will only be allowed if there is a select permission on the table type.
When the `--infer-function-permissions` flag is set to `true` or the flag is omitted (defaults to `true`), the permission of the function is inferred from the select permissions from the target table of the function, only for stable/immutable functions. Volatile functions are not exposed to any of the roles in this case. When the `--infer-function-permissions` flag is set to `true` or the flag is omitted (defaults to `true`), the permission of the function is inferred from the select permissions from the target table of the function, only for stable/immutable functions. Volatile functions are not exposed to any of the roles in this case.
@ -732,8 +758,8 @@ When the `--infer-function-permissions` flag is set to `true` or the flag is omi
</td> </td>
<td> <td>
List of experimental features to be enabled. A comma separated value is expected. Options: List of experimental features to be enabled. A comma separated value is expected. Options:
`inherited_roles`. `inherited_roles, optimize_permission_filters, streaming_subscriptions`.
<em>(Available for versions > v2.0.0)</em> <em>(Available for versions > v2.0.0)</em>
@ -801,8 +827,8 @@ Disable updating of metadata on the server (default: `false`)
</td> </td>
<td> <td>
Used to set the `Keep Alive` delay for client that use the Used to set the `Keep Alive` delay for client that use the
`subscription-transport-ws` (Apollo) protocol. For `graphql-ws` clients the graphql-engine sends `subscription-transport-ws` (Apollo) protocol. For `graphql-ws` clients the graphql-engine sends
`PING` messages instead. `PING` messages instead.
(default: `5`) (default: `5`)
@ -824,8 +850,8 @@ Used to set the `Keep Alive` delay for client that use the
</td> </td>
<td> <td>
Used to set the connection initialisation timeout for Used to set the connection initialisation timeout for
`graphql-ws` clients. This is ignored for `graphql-ws` clients. This is ignored for
`subscription-transport-ws` (Apollo) clients. `subscription-transport-ws` (Apollo) clients.
(default: `3`) (default: `3`)
@ -840,4 +866,4 @@ Used to set the connection initialisation timeout for
When the equivalent flags for environment variables are used, the flags When the equivalent flags for environment variables are used, the flags
will take precedence. will take precedence.
::: :::