Souscriptions
En plus de récupérer des données à l’aide de requêtes et de modifier des données à l’aide de mutations, la spécification GraphQL prend en charge un troisième type d’opération, appelé subscription
. Les souscriptions GraphQL permettent d’envoyer des données du serveur aux clients qui choisissent d’écouter les messages en temps réel du serveur. Les souscriptions sont similaires aux requêtes en ce sens qu’elles spécifient un ensemble de champs à livrer au client, mais au lieu de retourner immédiatement une seule réponse, une connexion est ouverte et un résultat est envoyé au client chaque fois qu’un événement particulier se produit sur le serveur.
Un cas d’utilisation courant pour les souscriptions est de notifier le client de certains événements, par exemple la création d’un nouvel objet, des champs mis à jour, etc. (lisez plus ici).
Activer les souscriptions avec le pilote Apollo
Pour activer les souscriptions, définissez la propriété installSubscriptionHandlers
sur true
.
GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, installSubscriptionHandlers: true,});
Pour switcher vers le package graphql-ws
, utilisez la configuration suivante :
GraphQLModule.forRoot<ApolloDriverConfig>({ driver: ApolloDriver, subscriptions: { 'graphql-ws': true, },});
Premier code
Pour créer une souscription en utilisant l’approche de premier code, nous utilisons le décorateur @Subscription()
(exporté du package @nestjs/graphql
) et la classe PubSub
du package graphql-subscriptions
, qui fournit une simple API de publication/souscription.
Le gestionnaire de souscription suivant s’occupe de se souscrire à un événement en appelant PubSub#asyncIterator
. Cette méthode prend un seul argument, le triggerName
, qui correspond à un nom de sujet d’événement.
const pubSub = new PubSub();
@Resolver(() => Author)export class AuthorResolver { @Subscription(() => Comment) commentAdded() { return pubSub.asyncIterator('commentAdded'); }}
Publier
Pour publier l’événement, nous utilisons la méthode PubSub#publish
. Cela est souvent utilisé dans une mutation pour déclencher une mise à jour côté client lorsque une partie de l’objet graphique a changé. Par exemple :
@Mutation(() => Post)async addComment( @Args('postId', { type: () => Int }) postId: number, @Args('comment') comment: CommentInput,) { const newComment = await this.commentsService.addComment({ id: postId, comment }); await pubSub.publish('commentAdded', { commentAdded: newComment }); return newComment;}
Comme mentionné, la souscription, par définition, retourne une valeur et cette valeur a une structure. Regardez encore une fois la SDL générée pour notre souscription commentAdded
:
type Subscription { commentAdded: Comment!}
Cela nous dit que la souscription doit retourner un objet avec une propriété de niveau supérieur nommée commentAdded
qui a une valeur qui est un objet Comment
. L’important à noter est que la forme de la charge utile de l’événement émise par la méthode PubSub#publish
doit correspondre à la forme de la valeur attendue pour être retournée par la souscription. Donc, dans notre exemple ci-dessus, l’instruction pubSub.publish('commentAdded', { commentAdded: newComment })
publie un événement commentAdded
avec la charge utile de forme appropriée. Si ces formes ne correspondent pas, votre souscription échouera lors de la phase de validation GraphQL.
Filtrage des souscriptions
Pour filtrer des événements spécifiques, définissez la propriété filter
sur une fonction de filtre. Cette fonction agit de manière similaire à la fonction passée à un tableau filter
. Elle prend deux arguments : payload
contenant la charge utile de l’événement (telle qu’envoyée par l’éditeur d’événements), et variables
prenant tous les arguments passés lors de la demande de souscription. Elle retourne un booléen déterminant si cet événement doit être publié aux auditeurs du client.
@Subscription(() => Comment, { filter: (payload, variables) => payload.commentAdded.title === variables.title,})commentAdded(@Args('title') title: string) { return pubSub.asyncIterator('commentAdded');}
Payload de souscription
Pour modifier le payload de l’événement publié, définissez la propriété resolve
sur une fonction. La fonction reçoit le payload de l’événement (tel qu’envoyé par l’éditeur d’événements) et retourne la valeur appropriée :
@Subscription(() => Comment, { resolve: value => value,})commentAdded() { return pubSub.asyncIterator('commentAdded');}
Le même construction fonctionne avec des filtres.
…
type Subscription { ...}
Cet exemple montre comment gérer les souscriptions en utilisant un modèle de développement avec NestJS et GraphQL. Il décrit comment les activer, publier des événements, et gérer les paramètres et payloads de manière efficace.