首页 > 解决方案 > Nest.JS graphql 获取请求的字段

问题描述

在 Nest.js Graphql 中,是否可以从解析器中获取所需的字段列表?要确定执行哪些连接,哪些不执行,例如对于这个 db 模式:

Employee
 id
 employer_id
 name

Employer
 id
 name

如果是以下 graphql 查询:

  query {
    employees {
      id
      name
      employer {
        id
      }
    }
  }

无需从数据库中获取/加入雇主数据,因为可以从雇员表中访问雇主 ID。

标签: typescriptgraphqlnestjs

解决方案


基本上,您可以使用来自 NestJs 的 @Info https://docs.nestjs.com/graphql/resolvers#graphql-argument-decoratorsinfo装饰器,它从常规阿波罗解析器返回一个参数。

这个装饰器将解析后的 GraphQL 查询作为 AST 注入,并允许用户创建更复杂的解析器。

使用 AST 并不简单和容易,因为您需要自己处理所有查询类型(片段、别名、指令等),但幸运的是,市场上有一些库可以在后台完成所有繁重的工作。

@jenyus-org/graphql-utils

https://www.npmjs.com/package/@jenyus-org/graphql-utils

这对于 NestJS 也有非常有用的装饰器:

https://www.npmjs.com/package/@jenyus-org/nestjs-graphql-utils

代码

@Query(() => [PostObject])
async posts(
  @FieldMap() fieldMap: FieldMap,
) {
  console.log(fieldMap);
}

输出

{
  "posts": {
    "id": {},
    "title": {},
    "body": {},
    "author": {
      "id": {},
      "username": {},
      "firstName": {},
      "lastName": {}
    },
    "comments": {
      "id": {},
      "body": {},
      "author": {
        "id": {},
        "username": {},
        "firstName": {},
        "lastName": {}
      }
    }
  }
}

graphql 字段列表

https://www.npmjs.com/package/graphql-fields-list

NestJS 中的示例:

{
  post { # post: [Post]
    id
    author: {
      id
      firstName
      lastName
    }
  }
}
import { fieldsList, fieldsMap } from 'graphql-fields-list';
import { Query, Info } from '@nestjs/graphql';

@Query(() => [Post])
async post(
  @Info() info,
) {
  console.log(fieldsList(info));       // [ 'id', 'firstName', 'lastName' ]
  console.log(fieldsMap(info));        // { id: false, firstName: false, lastName: false }
  console.log(fieldsProjection(info)); // { id: 1, firstName: 1, lastName: 1 };
}

其他类似的库

https://www.npmjs.com/package/graphql-parse-resolve-info https://github.com/robrichard/graphql-fields


推荐阅读