diff options
Diffstat (limited to 'doc/development/api_graphql_styleguide.md')
-rw-r--r-- | doc/development/api_graphql_styleguide.md | 41 |
1 files changed, 38 insertions, 3 deletions
diff --git a/doc/development/api_graphql_styleguide.md b/doc/development/api_graphql_styleguide.md index e8b71e0509a..4d521d11a69 100644 --- a/doc/development/api_graphql_styleguide.md +++ b/doc/development/api_graphql_styleguide.md @@ -16,7 +16,7 @@ We use the [GraphQL Ruby gem](https://graphql-ruby.org/) written by [Robert Moso In addition, we have a subscription to [GraphQL Pro](https://graphql.pro/). For details see [GraphQL Pro subscription](graphql_guide/graphql_pro.md). All GraphQL queries are directed to a single endpoint -([`app/controllers/graphql_controller.rb#execute`](https://gitlab.com/gitlab-org/gitlab/blob/master/app%2Fcontrollers%2Fgraphql_controller.rb)), +([`app/controllers/graphql_controller.rb#execute`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app%2Fcontrollers%2Fgraphql_controller.rb)), which is exposed as an API endpoint at `/api/graphql`. ## Deep Dive @@ -862,7 +862,7 @@ overhead. If you are writing: Resolvers may raise errors, which will be converted to top-level errors as appropriate. All anticipated errors should be caught and transformed to an appropriate GraphQL error (see -[`Gitlab::Graphql::Errors`](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/graphql/errors.rb)). +[`Gitlab::Graphql::Errors`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/graphql/errors.rb)). Any uncaught errors will be suppressed and the client will receive the message `Internal service error`. @@ -1575,6 +1575,41 @@ deprecated aliased mutations. EE mutations should follow the same process. For an example of the merge request process, read [merge request !42588](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/42588). +## Subscriptions + +We use subscriptions to push updates to clients. We use the [Action Cable implementation](https://graphql-ruby.org/subscriptions/action_cable_implementation) +to deliver the messages over websockets. + +When a client subscribes to a subscription, we store their query in-memory within Puma workers. Then when the subscription is triggered, +the Puma workers execute the stored GraphQL queries and push the results to the clients. + +NOTE: +We cannot test subscriptions using GraphiQL, because they require an Action Cable client, which GraphiQL does not support at the moment. + +### Building subscriptions + +All fields under `Types::SubscriptionType` are subscriptions that clients can subscribe to. These fields require a subscription class, +which is a descendant of `Subscriptions::BaseSubscription` and is stored under `app/graphql/subscriptions`. + +The arguments required to subscribe and the fields that are returned are defined within the subscription class. Multiple fields can share +the same subscription class if they have the same arguments and return the same fields. + +This class runs during the initial subscription request and subsequent updates. You can read more about this in the +[GraphQL Ruby guides](https://graphql-ruby.org/subscriptions/subscription_classes). + +### Authorization + +You should implement the `#authorized?` method of the subscription class so that the initial subscription and subsequent updates are authorized. + +When a user is not authorized, you should call the `unauthorized!` helper so that execution is halted and the user is unsubscribed. Returning `false` +results in redaction of the response but we leak information that some updates are happening. This is due to a +[bug in the GraphQL gem](https://github.com/rmosolgo/graphql-ruby/issues/3390). + +### Triggering subscriptions + +Define a method under the `GraphqlTriggers` module to trigger a subscription. Do not call `GitlabSchema.subscriptions.trigger` directly in application +code so that we have a single source of truth and we do not trigger a subscription with different arguments and objects. + ## Pagination implementation To learn more, visit [GraphQL pagination](graphql_guide/pagination.md). @@ -1614,7 +1649,7 @@ is merged. ### `Types::TimeType` -[`Types::TimeType`](https://gitlab.com/gitlab-org/gitlab/blob/master/app%2Fgraphql%2Ftypes%2Ftime_type.rb) +[`Types::TimeType`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/app%2Fgraphql%2Ftypes%2Ftime_type.rb) must be used as the type for all fields and arguments that deal with Ruby `Time` and `DateTime` objects. |