Unionlar
Union turlari interfeyslarga juda o'xshaydi, ammo ular turlar orasida umumiy maydonlarni belgilay olmaydi (batafsil here). Unionlar bitta maydondan o'zaro kesishmaydigan ma'lumot t
Union turlari interfeyslarga juda o'xshaydi, ammo ular turlar orasida umumiy maydonlarni belgilay olmaydi (batafsil here). Unionlar bitta maydondan o'zaro kesishmaydigan ma'lumot turlarini qaytarishda foydali.
Code first yondashuvi
GraphQL union turini aniqlash uchun bu union tarkibini tashkil etadigan klasslarni belgilashimiz kerak. Apollo hujjatlaridagi example asosida ikki klass yaratamiz. Avval Book:
1import { Field, ObjectType } from '@nestjs/graphql';
2
3@ObjectType()
4export class Book {
5 @Field()
6 title: string;
7}Keyin Author:
1import { Field, ObjectType } from '@nestjs/graphql';
2
3@ObjectType()
4export class Author {
5 @Field()
6 name: string;
7}Shu bilan, @nestjs/graphql paketidan eksport qilinadigan createUnionType funksiyasi orqali ResultUnion unionini ro'yxatdan o'tkazing:
1export const ResultUnion = createUnionType({
2 name: 'ResultUnion',
3 types: () => [Author, Book] as const,
4});createUnionType funksiyasining types propertysi qaytargan massivga const assertion berilishi kerak. Agar const assertion berilmasa, kompilyatsiya vaqtida noto'g'ri deklaratsiya fayli generatsiya qilinadi va uni boshqa loyihadan ishlatganda xato yuz beradi.
Endi biz so'rovda ResultUnionni ko'rsatishimiz mumkin:
1@Query(() => [ResultUnion])
2search(): Array<typeof ResultUnion> {
3 return [new Author(), new Book()];
4}Bu SDL formatida GraphQL sxemasining quyidagi qismini generatsiya qiladi:
1type Author {
2 name: String!
3}
4
5type Book {
6 title: String!
7}
8
9union ResultUnion = Author | Book
10
11type Query {
12 search: [ResultUnion!]!
13}Kutubxona yaratadigan standart resolveType() funksiyasi type ni resolver metodidan qaytarilgan qiymat asosida aniqlaydi. Bu, literal JavaScript obyektlar emas, balki klass instansiyalarini qaytarish majburiyligini anglatadi.
Moslashtirilgan resolveType() funksiyasini berish uchun createUnionType() funksiyasiga uzatiladigan options obyektiga resolveType propertysini quyidagicha kiriting:
1export const ResultUnion = createUnionType({
2 name: 'ResultUnion',
3 types: () => [Author, Book] as const,
4 resolveType(value) {
5 if (value.name) {
6 return Author;
7 }
8 if (value.title) {
9 return Book;
10 }
11 return null;
12 },
13});Schema first yondashuvi
Schema first yondashuvida unionni aniqlash uchun SDL bilan GraphQL union yarating.
1type Author {
2 name: String!
3}
4
5type Book {
6 title: String!
7}
8
9union ResultUnion = Author | BookSo'ng, mos TypeScript ta'riflarini yaratish uchun tiplashlarni generatsiya qilish funksiyasidan foydalanishingiz mumkin (bu quick start bobida ko'rsatilgan):
1export class Author {
2 name: string;
3}
4
5export class Book {
6 title: string;
7}
8
9export type ResultUnion = Author | Book;Unionlar resolver map ichida union qaysi turga yechilishini aniqlash uchun qo'shimcha __resolveType maydonini talab qiladi. Shuningdek, ResultUnionResolver klassi har qanday modulda provider sifatida ro'yxatdan o'tkazilishi kerakligini unutmang. ResultUnionResolver klassini yaratib, __resolveType metodini aniqlaymiz.
1@Resolver('ResultUnion')
2export class ResultUnionResolver {
3 @ResolveField()
4 __resolveType(value) {
5 if (value.name) {
6 return 'Author';
7 }
8 if (value.title) {
9 return 'Book';
10 }
11 return null;
12 }
13}Barcha dekoratorlar @nestjs/graphql paketidan eksport qilinadi.
Enumlar
Enumeration turlari muayyan ruxsat etilgan qiymatlar to'plami bilan cheklangan skalyarning maxsus turi (batafsil here). Bu sizga quyidagilarga imkon beradi:
- bu turdagi har qanday argument ruxsat etilgan qiymatlardan biri ekanini tekshirish
- type tizimi orqali maydon har doim yakunli qiymatlar to'plamidan biri bo'lishini ko'rsatish
Code first yondashuvi
Code first yondashuvida GraphQL enum turini aniqlash uchun shunchaki TypeScript enum yaratasiz.
1export enum AllowedColor {
2 RED,
3 GREEN,
4 BLUE,
5}Shu bilan, @nestjs/graphql paketidan eksport qilinadigan registerEnumType funksiyasi yordamida AllowedColor enumini ro'yxatdan o'tkazing:
1registerEnumType(AllowedColor, {
2 name: 'AllowedColor',
3});Endi turlaringizda AllowedColorni ko'rsatishingiz mumkin:
1@Field(type => AllowedColor)
2favoriteColor: AllowedColor;Bu SDL formatida GraphQL sxemasining quyidagi qismini generatsiya qiladi:
1enum AllowedColor {
2 RED
3 GREEN
4 BLUE
5}Enum uchun tavsif berish uchun registerEnumType() funksiyasiga description propertysini uzating.
1registerEnumType(AllowedColor, {
2 name: 'AllowedColor',
3 description: 'The supported colors.',
4});Enum qiymatlari uchun tavsif berish yoki qiymatni deprecated deb belgilash uchun valuesMap propertysini quyidagicha uzating:
1registerEnumType(AllowedColor, {
2 name: 'AllowedColor',
3 description: 'The supported colors.',
4 valuesMap: {
5 RED: {
6 description: 'The default color.',
7 },
8 BLUE: {
9 deprecationReason: 'Too blue.',
10 },
11 },
12});Bu SDL formatida quyidagi GraphQL sxemasini generatsiya qiladi:
1"""
2The supported colors.
3"""
4enum AllowedColor {
5 """
6 The default color.
7 """
8 RED
9 GREEN
10 BLUE @deprecated(reason: "Too blue.")
11}Schema first yondashuvi
Schema first yondashuvida enumeratorni aniqlash uchun SDL bilan GraphQL enum yarating.
1enum AllowedColor {
2 RED
3 GREEN
4 BLUE
5}So'ng, mos TypeScript ta'riflarini yaratish uchun tiplashlarni generatsiya qilish funksiyasidan foydalanishingiz mumkin (bu quick start bobida ko'rsatilgan):
1export enum AllowedColor {
2 RED
3 GREEN
4 BLUE
5}Ba'zan backend enumning qiymatini public API dagidan ichkarida boshqacha majburlashi mumkin. Bu misolda API RED ni o'z ichiga oladi, ammo resolverlarda buning o'rniga #f00 ishlatishimiz mumkin (batafsil here). Buni bajarish uchun AllowedColor enumi uchun resolver obyektini e'lon qiling:
1export const allowedColorResolver: Record<keyof typeof AllowedColor, any> = {
2 RED: '#f00',
3};Barcha dekoratorlar @nestjs/graphql paketidan eksport qilinadi.
So'ng bu resolver obyektini GraphQLModule#forRoot() metodining resolvers propertysi bilan birga quyidagicha ishlating:
1GraphQLModule.forRoot({
2 resolvers: {
3 AllowedColor: allowedColorResolver,
4 },
5});