Directives
Une directive peut être attachée à un champ ou une inclusion de fragment, et peut affecter l’exécution de la requête comme le souhaite le serveur (lisez-en plus ici). La spécification GraphQL fournit plusieurs directives par défaut :
@include(if: Boolean)
- n’incluez ce champ dans le résultat que si l’argument est vrai@skip(if: Boolean)
- sautez ce champ si l’argument est vrai@deprecated(reason: String)
- marque le champ comme obsolète avec un message
Une directive est un identifiant précédé d’un caractère @
, éventuellement suivi d’une liste d’arguments nommés, qui peuvent apparaître après presque n’importe quel élément dans les langages de requêtes et de schéma GraphQL.
Directives personnalisées
Pour indiquer ce qui doit se passer lorsque Apollo/Mercurius rencontre votre directive, vous pouvez créer une fonction de transformation. Cette fonction utilise la fonction mapSchema
pour itérer à travers les emplacements de votre schéma (définitions de champ, définitions de type, etc.) et effectuer les transformations correspondantes.
import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';import { defaultFieldResolver, GraphQLSchema } from 'graphql';
export function upperDirectiveTransformer( schema: GraphQLSchema, directiveName: string,) { return mapSchema(schema, { [MapperKind.OBJECT_FIELD]: (fieldConfig) => { const upperDirective = getDirective(schema, fieldConfig, directiveName)?.[0];
if (upperDirective) { const { resolve = defaultFieldResolver } = fieldConfig;
// Remplacez le résolveur original par une fonction qui d'abord appelle // le résolveur original, puis convertit son résultat en majuscules fieldConfig.resolve = async function (source, args, context, info) { const result = await resolve(source, args, context, info); if (typeof result === 'string') { return result.toUpperCase(); } return result; }; return fieldConfig; } }, });}
Maintenant, appliquez la fonction de transformation upperDirectiveTransformer
dans la méthode GraphQLModule#forRoot
en utilisant la fonction transformSchema
:
GraphQLModule.forRoot({ // ... transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),});
Une fois enregistrée, la directive @upper
peut être utilisée dans notre schéma. Toutefois, la manière d’appliquer la directive variera selon l’approche que vous utilisez (premier code ou premier schéma).
Premier code
Dans l’approche premier code, utilisez le décorateur @Directive()
pour appliquer la directive.
@Directive('@upper')@Field()title: string;
Les directives peuvent être appliquées sur des champs, des résolveurs de champ, des types d’entrée et d’objet, ainsi que sur des requêtes, des mutations et des abonnements. Voici un exemple de la directive appliquée au niveau du gestionnaire de requêtes :
@Directive('@deprecated(reason: "Cette requête sera supprimée dans la prochaine version")')@Query(returns => Author, { name: 'author' })async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) { return this.authorsService.findOneById(id);}
Enfin, assurez-vous de déclarer les directives dans le GraphQLModule
, comme suit :
GraphQLModule.forRoot({ // ... transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'), buildSchemaOptions: { directives: [ new GraphQLDirective({ name: 'upper', locations: [DirectiveLocation.FIELD_DEFINITION], }), ], },});
Premier schéma
Dans l’approche premier schéma, appliquez les directives directement dans SDL.
directive @upper on FIELD_DEFINITION
type Post { id: Int! title: String! @upper votes: Int}