Вложенное поле в Nest
В ответе уже есть заголовок и ссылка на автора, но имя автора лежит в другом массиве. Если склеивать всё заранее, лишние данные уйдут клиенту даже когда поле автора в запросе не просили.
Вложенное поле
считают методом с
ResolveField:
он получает родительский
объект из параметра
Parent и ищет
соседа по идентификатору
в своём хранилище.
GraphQL вызовет его только
если клиент указал это поле
в тексте запроса.
Покажем на примере постов:
import { Field, ObjectType } from '@nestjs/graphql';
@ObjectType()
export class Post {
@Field()
id: string;
@Field()
title: string;
@Field()
authorId: string;
}
@ObjectType()
export class Author {
@Field()
id: string;
@Field()
name: string;
}
Сервис авторов держит отдельный массив:
import { Injectable } from '@nestjs/common';
import { Author } from './post.model.js';
@Injectable()
export class AuthorService {
authors: Author[] = [
{ id: 'a1', name: 'Иван' },
{ id: 'a2', name: 'Мария' },
];
findById(id: string): Author | null {
return this.authors.find((item) => item.id === id) ?? null;
}
}
Резолвер отдаёт посты и подгружает автора по полю родителя:
import { Parent, Query, ResolveField, Resolver } from '@nestjs/graphql';
import { AuthorService } from './author.service.js';
import { Author, Post } from './post.model.js';
@Resolver(() => Post)
export class PostResolver {
rows: Post[] = [
{ id: '1', title: 'Первый', authorId: 'a1' },
{ id: '2', title: 'Второй', authorId: 'a2' },
];
authorService: AuthorService;
constructor(authorService: AuthorService) {
this.authorService = authorService;
}
@Query(() => [Post])
posts(): Post[] {
return this.rows;
}
@ResolveField(() => Author, { nullable: true })
author(@Parent() post: Post): Author | null {
return this.authorService.findById(post.authorId);
}
}
Регистрация в корневом модуле:
import { Module } from '@nestjs/common';
import { GraphQLModule } from '@nestjs/graphql';
import { ApolloDriver, ApolloDriverConfig } from '@nestjs/apollo';
import { AuthorService } from './author.service.js';
import { PostResolver } from './post.resolver.js';
@Module({
imports: [
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
autoSchemaFile: true,
}),
],
providers: [PostResolver, AuthorService],
})
export class AppModule {}
Опишите тип работника
со ссылкой на отдел,
храните отделы в DepartmentService
и верните название отдела
через WorkerResolver
только когда клиент запросил
это поле.