TypeScript va GraphQL qudratidan foydalanish
GraphQL - bu APIlar uchun kuchli query tili va mavjud ma'lumotlaringiz bilan ushbu so'rovlarni bajarish uchun runtime. Bu REST APIlarda ko'p uchraydigan muammolarni hal qiladigan n
GraphQL - bu APIlar uchun kuchli query tili va mavjud ma'lumotlaringiz bilan ushbu so'rovlarni bajarish uchun runtime. Bu REST APIlarda ko'p uchraydigan muammolarni hal qiladigan nafis yondashuv. Asosiy ma'lumot uchun GraphQL va REST taqqoslanadigan ushbu taqqoslashni o'qishni tavsiya qilamiz. GraphQL bilan birga TypeScriptdan foydalanish GraphQL so'rovlari uchun yaxshiroq type safety beradi va end-to-end typingni ta'minlaydi.
Bu bobda GraphQL haqida asosiy tushunchalar bor deb faraz qilamiz va ichki @nestjs/graphql moduli bilan qanday ishlashga e'tibor qaratamiz. GraphQLModuleni Apollo server ( @nestjs/apollo driveri bilan) va Mercurius (@nestjs/mercurius bilan) uchun sozlash mumkin. Biz ushbu ishonchli GraphQL paketlari uchun rasmiy integratsiyalarni taqdim etamiz, shunda Nest bilan GraphQLdan foydalanish oson bo'ladi (batafsil integratsiyalar bu yerda).
Shuningdek, o'zingizning maxsus driveringizni yaratishingiz ham mumkin (batafsil bu yerda).
O'rnatish
Avval kerakli paketlarni o'rnating:
1# For Express and Apollo (default)
2$ npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/express5 graphql
3
4# For Fastify and Apollo
5# npm i @nestjs/graphql @nestjs/apollo @apollo/server @as-integrations/fastify graphql
6
7# For Fastify and Mercurius
8# npm i @nestjs/graphql @nestjs/mercurius graphql mercurius@nestjs/graphql@>=9 va @nestjs/apollo^10 paketlari Apollo v3 bilan mos (batafsil Apollo Server 3 migration guide), @nestjs/graphql@^8 esa faqat Apollo v2 ni qo'llab-quvvatlaydi (masalan, apollo-server-express@2.x.x paketi).
Umumiy ko'rinish
Nest GraphQL ilovalarini yaratishning ikki usulini taklif qiladi: code first va schema first. Sizga eng mos keladiganini tanlang. GraphQL bo'limining ko'p boblari ikki qismga bo'lingan: biri code first qabul qilganlar uchun, ikkinchisi schema first qabul qilganlar uchun.
Code first yondashuvida siz dekoratorlar va TypeScript klasslari yordamida GraphQL schema ni generatsiya qilasiz. Bu yondashuv faqat TypeScript bilan ishlashni afzal ko'radigan va til sintaksislari orasida kontekst almashishni istamaydiganlar uchun qulay.
Schema first yondashuvida asosiy manba GraphQL SDL (Schema Definition Language) fayllari bo'ladi. SDL - schema fayllarini turli platformalar o'rtasida bo'lishishning tilga bog'liq bo'lmagan usuli. Nest GraphQL schemalar asosida TypeScript ta'riflarini (klasslar yoki interfeyslar) avtomatik yaratadi, bu ortiqcha boilerplate yozishni kamaytiradi.
GraphQL va TypeScript bilan boshlash
Keyingi bo'limlarda @nestjs/apollo paketini integratsiya qilamiz. Agar mercuriusdan foydalanmoqchi bo'lsangiz, bu bo'limga o'ting.
Paketlar o'rnatilgach, GraphQLModuleni import qilib, uni forRoot() statik metodi bilan sozlashimiz mumkin.
1import { Module } from '@nestjs/common';
2import { GraphQLModule } from '@nestjs/graphql';
3import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
4
5@Module({
6 imports: [
7 GraphQLModule.forRoot<ApolloDriverConfig>({
8 driver: ApolloDriver,
9 }),
10 ],
11})
12export class AppModule {}mercurius integratsiyasi uchun MercuriusDriver va MercuriusDriverConfig ishlatishingiz kerak. Ikkalasi ham @nestjs/mercurius paketidan eksport qilinadi.
forRoot() metodi argument sifatida opsiyalar obyektini qabul qiladi. Bu opsiyalar ichki driver instansiyasiga uzatiladi (mavjud sozlamalar haqida batafsil: Apollo va Mercurius). Masalan, playgroundni o'chirish va debug rejimini o'chirishni xohlasangiz (Apollo uchun), quyidagi opsiyalarni bering:
1import { Module } from '@nestjs/common';
2import { GraphQLModule } from '@nestjs/graphql';
3import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
4
5@Module({
6 imports: [
7 GraphQLModule.forRoot<ApolloDriverConfig>({
8 driver: ApolloDriver,
9 playground: false,
10 }),
11 ],
12})
13export class AppModule {}Bu holatda opsiyalar ApolloServer konstruktoriga uzatiladi.
GraphQL playground
Playground - bu GraphQL serverining o'zi bilan bir xil URLda default mavjud bo'lgan grafik, interaktiv, brauzerdagi GraphQL IDE. Playgroundga kirish uchun oddiy GraphQL server sozlangan va ishlayotgan bo'lishi kerak. Uni hoziroq ko'rish uchun bu yerda ishlaydigan misolni o'rnatib ishga tushirishingiz mumkin. Yoki agar shu kod namunalarini bosqichma-bosqich bajarayotgan bo'lsangiz, Resolvers bobidagi qadamlarni tugatganingizdan so'ng playgroundga kirishingiz mumkin.
Shu bilan va ilovangiz fon rejimida ishlayotganida, brauzeringizni ochib http://localhost:3000/graphql manziliga o'ting (host va port konfiguratsiyangizga qarab farq qiladi). Shunda siz quyida ko'rsatilgandek GraphQL playgroundni ko'rasiz.
@nestjs/mercurius integratsiyasida built-in GraphQL Playground yo'q. Buning o'rniga GraphiQLdan foydalanishingiz mumkin (graphiql: true qilib qo'ying).
Yangilanish (04/14/2025): Default Apollo playground eskirgan va keyingi major release da olib tashlanadi. Buning o'rniga GraphiQLdan foydalanishingiz mumkin, shunchaki GraphQLModule konfiguratsiyasida graphiql: true qilib qo'ying, quyida ko'rsatilgandek:
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
graphiql: true,
}),
Agar ilovangizda subscriptions bo'lsa, graphql-wsdan foydalaning, chunki subscriptions-transport-ws GraphiQL tomonidan qo'llab-quvvatlanmaydi.
Code first
Code first yondashuvida siz dekoratorlar va TypeScript klasslari yordamida GraphQL schema ni generatsiya qilasiz.
Code first yondashuvini ishlatish uchun opsiyalar obyektiga autoSchemaFile xossasini qo'shing:
1GraphQLModule.forRoot<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
4}),autoSchemaFile xossasi qiymati avtomatik generatsiya qilingan schema saqlanadigan yo'lni bildiradi. Muqobil ravishda, schema on-the-fly tarzda xotirada generatsiya qilinishi mumkin. Buni yoqish uchun autoSchemaFile ni true qilib qo'ying:
1GraphQLModule.forRoot<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 autoSchemaFile: true,
4}),Default holatda generatsiya qilingan schemadagi turlar kiritilgan modullardagi ta'rif tartibida bo'ladi. Schemani leksikografik tartibda saralash uchun sortSchema xossasini true qiling:
1GraphQLModule.forRoot<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 autoSchemaFile: join(process.cwd(), 'src/schema.gql'),
4 sortSchema: true,
5}),Misol
To'liq ishlaydigan code first misol bu yerda mavjud.
Schema first
Schema first yondashuvini ishlatish uchun opsiyalar obyektiga typePaths xossasini qo'shing. typePaths xossasi GraphQLModule qayerdan GraphQL SDL schema definition fayllarini qidirishini ko'rsatadi. Bu fayllar xotirada birlashtiriladi; bu esa schemalarni bir nechta faylga bo'lish va ularni resolverlar yonida joylashtirish imkonini beradi.
1GraphQLModule.forRoot<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 typePaths: ['./**/*.graphql'],
4}),Odatda GraphQL SDL turlariga mos keladigan TypeScript ta'riflari (klasslar va interfeyslar) ham kerak bo'ladi. Bu ta'riflarni qo'lda yaratish ortiqcha va zerikarli. Bu bizni yagona haqiqat manbaisiz qoldiradi -- SDLdagi har bir o'zgarish TypeScript ta'riflarini ham moslashtirishni talab qiladi. Buni hal qilish uchun @nestjs/graphql paketi abstrakt sintaksis daraxti (AST) asosida TypeScript ta'riflarini avtomatik generatsiya qila oladi. Bu funksiyani yoqish uchun GraphQLModuleni sozlashda definitions opsiyasini qo'shing.
1GraphQLModule.forRoot<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 typePaths: ['./**/*.graphql'],
4 definitions: {
5 path: join(process.cwd(), 'src/graphql.ts'),
6 },
7}),definitions obyektidagi path xossasi generatsiya qilingan TypeScript outputni qayerga saqlashni bildiradi. Default holatda barcha generatsiya qilingan TypeScript turlar interfeys sifatida yaratiladi. Klasslar sifatida generatsiya qilish uchun outputAs xossasiga 'class' qiymatini bering.
1GraphQLModule.forRoot<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 typePaths: ['./**/*.graphql'],
4 definitions: {
5 path: join(process.cwd(), 'src/graphql.ts'),
6 outputAs: 'class',
7 },
8}),Yuqoridagi yondashuv ilova ishga tushganida TypeScript ta'riflarini har safar dinamik generatsiya qiladi. Muqobil ravishda, bularni talab bo'yicha generatsiya qiladigan oddiy skript yozishni afzal ko'rishingiz mumkin. Masalan, generate-typings.ts nomli skript yaratamiz:
1import { GraphQLDefinitionsFactory } from '@nestjs/graphql';
2import { join } from 'node:path';
3
4const definitionsFactory = new GraphQLDefinitionsFactory();
5definitionsFactory.generate({
6 typePaths: ['./src/**/*.graphql'],
7 path: join(process.cwd(), 'src/graphql.ts'),
8 outputAs: 'class',
9});Endi bu skriptni istalgan vaqtda ishga tushirishingiz mumkin:
1$ ts-node generate-typingsSkriptni oldindan kompilyatsiya qilib (masalan, tsc bilan) so'ng node orqali ishga tushirishingiz mumkin.
.graphql fayllaridagi har qanday o'zgarishda typelar avtomatik generatsiya qilinishi uchun generate() metodiga watch opsiyasini uzating.
1definitionsFactory.generate({
2 typePaths: ['./src/**/*.graphql'],
3 path: join(process.cwd(), 'src/graphql.ts'),
4 outputAs: 'class',
5 watch: true,
6});Har bir object type uchun qo'shimcha __typename fieldini avtomatik generatsiya qilish uchun emitTypenameField opsiyasini yoqing:
1definitionsFactory.generate({
2 // ...
3 emitTypenameField: true,
4});Resolverlarni (queries, mutations, subscriptions) argumentlarsiz oddiy fieldlar sifatida generatsiya qilish uchun skipResolverArgs opsiyasini yoqing:
1definitionsFactory.generate({
2 // ...
3 skipResolverArgs: true,
4});Enumlarni oddiy TypeScript enumlar o'rniga TypeScript union turlari sifatida generatsiya qilish uchun enumsAsTypes opsiyasini true qiling:
1definitionsFactory.generate({
2 // ...
3 enumsAsTypes: true,
4});Apollo Sandbox
Mahalliy ishlab chiqish uchun GraphQL IDE sifatida graphql-playground o'rniga Apollo Sandboxdan foydalanish uchun quyidagi konfiguratsiyadan foydalaning:
1import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
2import { Module } from '@nestjs/common';
3import { GraphQLModule } from '@nestjs/graphql';
4import { ApolloServerPluginLandingPageLocalDefault } from '@apollo/server/plugin/landingPage/default';
5
6@Module({
7 imports: [
8 GraphQLModule.forRoot<ApolloDriverConfig>({
9 driver: ApolloDriver,
10 playground: false,
11 plugins: [ApolloServerPluginLandingPageLocalDefault()],
12 }),
13 ],
14})
15export class AppModule {}Misol
To'liq ishlaydigan schema first misol bu yerda mavjud.
Generatsiya qilingan schemaga kirish
Ba'zi holatlarda (masalan, end-to-end testlarda) generatsiya qilingan schema obyektiga murojaat qilishni xohlashingiz mumkin. End-to-end testlarda HTTP listenerlardan foydalanmasdan graphql obyektidan so'rov yuborishingiz mumkin.
Generatsiya qilingan schemaga (code first yoki schema first yondashuvida) GraphQLSchemaHost klassi orqali kirishingiz mumkin:
1const { schema } = app.get(GraphQLSchemaHost);GraphQLSchemaHost#schema getterini ilova initsializatsiya qilingandan keyin ( app.listen() yoki app.init() metodi onModuleInit hookni ishga tushirgandan so'ng) chaqirishingiz kerak.
Async konfiguratsiya
Modul opsiyalarini statik emas, asinxron tarzda uzatish kerak bo'lganda forRootAsync() metodidan foydalaning. Aksariyat dinamik modullar kabi, Nest asinxron konfiguratsiya bilan ishlash uchun bir nechta usullarni taqdim etadi.
Usullardan biri - factory funksiyasidan foydalanish:
1 GraphQLModule.forRootAsync<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 useFactory: () => ({
4 typePaths: ['./**/*.graphql'],
5 }),
6}),Boshqa factory providerlar kabi, factory funksiyamiz async bo'lishi va inject orqali bog'liqliklarni qabul qilishi mumkin.
1GraphQLModule.forRootAsync<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 imports: [ConfigModule],
4 useFactory: async (configService: ConfigService) => ({
5 typePaths: configService.get<string>('GRAPHQL_TYPE_PATHS'),
6 }),
7 inject: [ConfigService],
8}),Muqobil ravishda, quyida ko'rsatilgandek, GraphQLModuleni factory o'rniga klass yordamida sozlashingiz mumkin:
1GraphQLModule.forRootAsync<ApolloDriverConfig>({
2 driver: ApolloDriver,
3 useClass: GqlConfigService,
4}),Yuqoridagi konstruktsiya GqlConfigService ni GraphQLModule ichida instansiyalaydi va opsiyalar obyektini yaratish uchun undan foydalanadi. E'tibor bering, bu misolda GqlConfigService GqlOptionsFactory interfeysini implementatsiya qilishi kerak, bu quyida ko'rsatilgan. GraphQLModule taqdim etilgan klass obyektining createGqlOptions() metodini chaqiradi.
1@Injectable()
2class GqlConfigService implements GqlOptionsFactory {
3 createGqlOptions(): ApolloDriverConfig {
4 return {
5 typePaths: ['./**/*.graphql'],
6 };
7 }
8}Agar GraphQLModule ichida private nusxa yaratmasdan mavjud opsiyalar providerni qayta ishlatmoqchi bo'lsangiz, useExisting sintaksisidan foydalaning.
1GraphQLModule.forRootAsync<ApolloDriverConfig>({
2 imports: [ConfigModule],
3 useExisting: ConfigService,
4}),Mercurius integratsiyasi
Apolloodan foydalanish o'rniga, Fastify foydalanuvchilari (batafsil bu yerda) muqobil ravishda @nestjs/mercurius driveridan foydalanishi mumkin.
1import { Module } from '@nestjs/common';
2import { GraphQLModule } from '@nestjs/graphql';
3import { MercuriusDriver, MercuriusDriverConfig } from '@nestjs/mercurius';
4
5@Module({
6 imports: [
7 GraphQLModule.forRoot<MercuriusDriverConfig>({
8 driver: MercuriusDriver,
9 graphiql: true,
10 }),
11 ],
12})
13export class AppModule {}Ilova ishga tushgach, brauzeringizni ochib http://localhost:3000/graphiql manziliga o'ting. Shunda GraphQL IDEni ko'rasiz.
forRoot() metodi argument sifatida opsiyalar obyektini qabul qiladi. Bu opsiyalar ichki driver instansiyasiga uzatiladi. Mavjud sozlamalar haqida batafsil bu yerda o'qing.
Bir nechta endpoint
@nestjs/graphql modulining yana bir foydali imkoniyati - bir vaqtning o'zida bir nechta endpointlarni xizmat qilish. Bu qaysi modullar qaysi endpointga kirishini tanlash imkonini beradi. Default holatda GraphQL butun ilova bo'ylab resolverlarni qidiradi. Bu skanni faqat modulning bir qismiga cheklash uchun include xossasidan foydalaning.
1GraphQLModule.forRoot({
2 include: [CatsModule],
3}),Agar bitta ilovada bir nechta GraphQL endpoint bilan @apollo/server va @as-integrations/fastify paketlaridan foydalansangiz, GraphQLModule konfiguratsiyasida disableHealthCheck sozlamasini yoqishni unutmang.
Uchinchi tomon integratsiyalari
- GraphQL Yoga
Misol
Ishlaydigan misol bu yerda mavjud.