NestJS+GraphQL单表数据如何返回指定嵌套响应结构?
问题解答
是否需要创建双实体
完全不需要创建两个指向同一张表的实体。
该方案技术上虽然可以强行实现,但会带来冗余的实体维护成本:后续表结构变更需要同步修改两个实体,容易出现字段不一致问题,完全没有必要采用。
可行实现方案
下面提供两种生产环境常用的实现方式,性能和直接查询单表完全一致:
- 方案1:GraphQL层单独封装嵌套结构(推荐,灵活度最高)
仅保留单个TypeORM员工实体映射表结构,嵌套结构完全在GraphQL层做组装,不用修改数据库层逻辑:- TypeORM实体定义
import { Entity, Column } from 'typeorm'; @Entity('employee') // 替换为你的实际表名 export class Employee { @Column() EmployeeNo: string; @Column() departmentId: string; @Column() DepartmentName: string; }- GraphQL类型定义
import { ObjectType, Field } from '@nestjs/graphql'; @ObjectType() class DepartmentType { @Field() departmentId: string; @Field() DepartmentName: string; } @ObjectType() export class EmployeeType { @Field() EmployeeNo: string; @Field(() => DepartmentType) Department: DepartmentType; }- Resolver逻辑
可以直接在查询方法中组装,也可以用@ResolveField单独解析部门字段,实现解耦:
import { Query, Resolver, ResolveField, Parent, Args } from '@nestjs/graphql'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Employee } from './employee.entity'; import { EmployeeType } from './employee.type'; @Resolver(() => EmployeeType) export class EmployeeResolver { constructor( @InjectRepository(Employee) private employeeRepo: Repository<Employee>, ) {} @Query(() => EmployeeType) async getEmployee(@Args('employeeNo') employeeNo: string) { return this.employeeRepo.findOneBy({ EmployeeNo: employeeNo }); } @ResolveField(() => DepartmentType) Department(@Parent() employee: Employee) { return { departmentId: employee.departmentId, DepartmentName: employee.DepartmentName, }; } } - 方案2:TypeORM层面使用嵌入式实体
如果你希望实体层也保留分层结构,可以用TypeORM的嵌入式实体特性,所有字段还是存储在同一张表中,无需拆分表:
用该方案查询出来的实体天然带有嵌套的Department结构,直接返回给GraphQL即可,无需额外组装。import { Entity, Column, Embeddable } from 'typeorm'; @Embeddable() class Department { @Column() departmentId: string; @Column() DepartmentName: string; } @Entity('employee') export class Employee { @Column() EmployeeNo: string; @Column(() => Department) Department: Department; }
内容的提问来源于stack exchange,提问作者extractor
相关产品推荐
相关产品推荐

