Murakkablik
So'rov murakkabligi muayyan fieldlar qanchalik murakkabligini belgilash va maksimal murakkablik asosida so'rovlarni cheklash imkonini beradi. G'oya - har bir field uchun murakkabli
Bu bob faqat code first yondashuviga tegishli.
So'rov murakkabligi muayyan fieldlar qanchalik murakkabligini belgilash va maksimal murakkablik asosida so'rovlarni cheklash imkonini beradi. G'oya - har bir field uchun murakkablikni oddiy son bilan belgilashdir. Keng tarqalgan default qiymat - har bir field uchun 1 murakkablik berish. Bundan tashqari, GraphQL so'rovi murakkabligini hisoblashni complexity estimatorlar bilan moslashtirish mumkin. Complexity estimator - bu field murakkabligini hisoblaydigan oddiy funksiya. Qoidaga istalgancha estimator qo'shishingiz mumkin, va ular ketma-ket bajariladi. Birinchi bo'lib sonli murakkablik qiymatini qaytargan estimator o'sha field uchun murakkablikni belgilaydi.
@nestjs/graphql paketi graphql-query-complexity kabi, cost analysis asosida yechim beradigan vositalar bilan juda yaxshi integratsiya qilinadi. Bu kutubxona yordamida juda qimmat deb baholangan so'rovlarni GraphQL serveringizda rad etishingiz mumkin.
O'rnatish
Undan foydalanishni boshlash uchun avval kerakli bog'liqlikni o'rnatamiz.
1$ npm install --save graphql-query-complexityBoshlash
O'rnatish jarayoni tugagach, ComplexityPlugin klassini aniqlashimiz mumkin:
1import { GraphQLSchemaHost } from '@nestjs/graphql';
2import { Plugin } from '@nestjs/apollo';
3import {
4 ApolloServerPlugin,
5 BaseContext,
6 GraphQLRequestListener,
7} from '@apollo/server';
8import { GraphQLError } from 'graphql';
9import {
10 fieldExtensionsEstimator,
11 getComplexity,
12 simpleEstimator,
13} from 'graphql-query-complexity';
14
15@Plugin()
16export class ComplexityPlugin implements ApolloServerPlugin {
17 constructor(private gqlSchemaHost: GraphQLSchemaHost) {}
18
19 async requestDidStart(): Promise<GraphQLRequestListener<BaseContext>> {
20 const maxComplexity = 20;
21 const { schema } = this.gqlSchemaHost;
22
23 return {
24 async didResolveOperation({ request, document }) {
25 const complexity = getComplexity({
26 schema,
27 operationName: request.operationName,
28 query: document,
29 variables: request.variables,
30 estimators: [
31 fieldExtensionsEstimator(),
32 simpleEstimator({ defaultComplexity: 1 }),
33 ],
34 });
35 if (complexity > maxComplexity) {
36 throw new GraphQLError(
37 `Query is too complex: ${complexity}. Maximum allowed complexity: ${maxComplexity}`,
38 );
39 }
40 console.log('Query Complexity:', complexity);
41 },
42 };
43 }
44}Namoyish uchun, maksimal ruxsat etilgan murakkablikni 20 deb belgiladik. Yuqoridagi misolda 2 ta estimator ishlatdik: simpleEstimator va fieldExtensionsEstimator.
simpleEstimator: har bir field uchun qat'iy murakkablikni qaytaradifieldExtensionsEstimator: schemadagi har bir field uchun murakkablik qiymatini field extensionsdan oladi
Bu klassni istalgan moduldagi providers massiviga qo'shishni unutmang.
Field darajasidagi murakkablik
Ushbu plagin bilan endi istalgan field uchun murakkablikni @Field() dekoratoriga uzatiladigan opsiyalar obyektidagi complexity xossasi orqali belgilashingiz mumkin:
1@Field({ complexity: 3 })
2title: string;Muqobil ravishda, estimator funksiyasini belgilashingiz mumkin:
1@Field({ complexity: (options: ComplexityEstimatorArgs) => ... })
2title: string;Query/Mutation darajasidagi murakkablik
Bundan tashqari, @Query() va @Mutation() dekoratorlari quyidagicha complexity xossasiga ega bo'lishi mumkin:
1@Query({ complexity: (options: ComplexityEstimatorArgs) => options.args.count * options.childComplexity })
2items(@Args('count') count: number) {
3 return this.itemsService.getItems({ count });
4}