Middleware de champ
Le middleware de champ vous permet d’exécuter du code arbitraire avant ou après qu’un champ soit résolu. Un middleware de champ peut être utilisé pour convertir le résultat d’un champ, valider les arguments d’un champ, ou même vérifier les rôles au niveau du champ (par exemple, requis pour accéder à un champ cible pour lequel une fonction de middleware est exécutée).
Vous pouvez connecter plusieurs fonctions de middleware à un champ. Dans ce cas, elles seront appelées en séquence le long de la chaîne où le middleware précédent décide d’appeler le suivant. L’ordre des fonctions de middleware dans le tableau middleware
est important. Le premier résolveur est la couche “la plus extérieure”, donc il est exécuté en premier et en dernier (similaire au package graphql-middleware
). Le deuxième résolveur est la couche “deuxième extérieure”, donc il est exécuté deuxième et avant-dernier.
Getting started
Commençons par créer un middleware simple qui enregistrera une valeur de champ avant qu’elle ne soit renvoyée au client :
import { FieldMiddleware, MiddlewareContext, NextFn } from '@nestjs/graphql';
const loggerMiddleware: FieldMiddleware = async ( ctx: MiddlewareContext, next: NextFn,) => { const value = await next(); console.log(value); return value;};
Notez que les middleware de champ doivent correspondre à l’interface FieldMiddleware
. Dans l’exemple ci-dessus, nous exécutons d’abord la fonction next()
(qui exécute le véritable résolveur de champ et renvoie une valeur de champ) puis, nous consignons cette valeur dans notre terminal. De plus, la valeur renvoyée par la fonction de middleware remplace complètement la valeur précédente et comme nous ne voulons pas apporter de modifications, nous renvoyons simplement la valeur d’origine.
Avec cela en place, nous pouvons enregistrer notre middleware directement dans le décorateur @Field()
, comme suit :
@ObjectType()export class Recipe { @Field({ middleware: [loggerMiddleware] }) title: string;}
Maintenant, chaque fois que nous demandons le champ title
du type d’objet Recipe
, la valeur originale du champ sera enregistrée dans la console.
De plus, comme mentionné ci-dessus, nous pouvons contrôler la valeur du champ depuis la fonction de middleware. À des fins de démonstration, capitalisons le titre d’une recette (si présent) :
const value = await next();return value?.toUpperCase();
Dans ce cas, chaque titre sera automatiquement mis en majuscules, lorsqu’il est demandé.
De même, vous pouvez lier un middleware de champ à un résolveur de champ personnalisé (une méthode annotée avec le décorateur @ResolveField()
), comme suit :
@ResolveField(() => String, { middleware: [loggerMiddleware] })title() { return 'Placeholder';}
Middleware de champ global
En plus de lier un middleware directement à un champ spécifique, vous pouvez également enregistrer une ou plusieurs fonctions de middleware globalement. Dans ce cas, elles seront automatiquement connectées à tous les champs de vos types d’objets.
GraphQLModule.forRoot({ autoSchemaFile: 'schema.gql', buildSchemaOptions: { fieldMiddleware: [loggerMiddleware], },});