Direktivlar
Direktiv field yoki fragment inclusion ga biriktirilishi va server xohlagan tarzda so'rov bajarilishiga ta'sir qilishi mumkin (batafsil bu yerda). GraphQL spetsifikatsiyasi bir nec
Direktiv field yoki fragment inclusion ga biriktirilishi va server xohlagan tarzda so'rov bajarilishiga ta'sir qilishi mumkin (batafsil bu yerda). GraphQL spetsifikatsiyasi bir nechta default direktivlarni taqdim etadi:
@include(if: Boolean)- argument true bo'lsa, bu fieldni natijaga qo'shadi@skip(if: Boolean)- argument true bo'lsa, bu fieldni o'tkazib yuboradi@deprecated(reason: String)- fieldni deprecate qilib belgilaydi va xabar ko'rsatadi
Direktiv - bu @ belgisi bilan boshlanadigan identifikator bo'lib, ixtiyoriy ravishda nomlangan argumentlar ro'yxati bilan keladi; u GraphQL so'rovi va schema tillarining deyarli istalgan elementidan keyin yozilishi mumkin.
Custom direktivlar
Apollo/Mercurius sizning direktivingizga duch kelganda nima qilishini belgilash uchun transformer funksiyasini yaratishingiz mumkin. Bu funksiya mapSchemadan foydalanib schema ichidagi joylarni (field ta'riflari, type ta'riflari va h.k.) aylanib chiqadi va mos transformatsiyalarni bajaradi.
1import { getDirective, MapperKind, mapSchema } from '@graphql-tools/utils';
2import { defaultFieldResolver, GraphQLSchema } from 'graphql';
3
4export function upperDirectiveTransformer(
5 schema: GraphQLSchema,
6 directiveName: string,
7) {
8 return mapSchema(schema, {
9 [MapperKind.OBJECT_FIELD]: (fieldConfig) => {
10 const upperDirective = getDirective(
11 schema,
12 fieldConfig,
13 directiveName,
14 )?.[0];
15
16 if (upperDirective) {
17 const { resolve = defaultFieldResolver } = fieldConfig;
18
19 // Replace the original resolver with a function that *first* calls
20 // the original resolver, then converts its result to upper case
21 fieldConfig.resolve = async function (source, args, context, info) {
22 const result = await resolve(source, args, context, info);
23 if (typeof result === 'string') {
24 return result.toUpperCase();
25 }
26 return result;
27 };
28 return fieldConfig;
29 }
30 },
31 });
32}Endi upperDirectiveTransformer transformatsiya funksiyasini GraphQLModule#forRoot metodida transformSchema funksiyasi orqali qo'llang:
1GraphQLModule.forRoot({
2 // ...
3 transformSchema: (schema) => upperDirectiveTransformer(schema, 'upper'),
4});Ro'yxatdan o'tkazilgach, @upper direktivini schemamizda ishlatish mumkin. Biroq direktivni qo'llash usuli siz ishlatayotgan yondashuvga bog'liq bo'ladi (code first yoki schema first).
Code first
Code first yondashuvida direktivni qo'llash uchun @Directive() dekoratoridan foydalaning.
1@Directive('@upper')
2@Field()
3title: string;@Directive() dekoratori @nestjs/graphql paketidan eksport qilinadi.
Direktivlar fieldlar, field resolverlar, input va object turlar, shuningdek query, mutation va subscriptionlarda qo'llanishi mumkin. Quyida query handler darajasida direktivni qo'llash misoli keltirilgan:
1@Directive('@deprecated(reason: "This query will be removed in the next version")')
2@Query(() => Author, { name: 'author' })
3async getAuthor(@Args({ name: 'id', type: () => Int }) id: number) {
4 return this.authorsService.findOneById(id);
5}warn Warning
@Directive()dekoratori orqali qo'llangan direktivlar generatsiya qilingan schema definition faylida aks ettirilmaydi.
Oxirida direktivlarni GraphQLModule da quyidagicha e'lon qilishni unutmang:
1GraphQLModule.forRoot({
2 // ...,
3 transformSchema: schema => upperDirectiveTransformer(schema, 'upper'),
4 buildSchemaOptions: {
5 directives: [
6 new GraphQLDirective({
7 name: 'upper',
8 locations: [DirectiveLocation.FIELD_DEFINITION],
9 }),
10 ],
11 },
12}),GraphQLDirective va DirectiveLocation ikkalasi ham graphql paketidan eksport qilinadi.
Schema first
Schema first yondashuvida direktivlarni bevosita SDL ichida qo'llang.
1directive @upper on FIELD_DEFINITION
2
3type Post {
4 id: Int!
5 title: String! @upper
6 votes: Int
7}