如何使用 type-graphql 解析器函数获取 graphql 后端中的选定字段?

Posted

技术标签:

【中文标题】如何使用 type-graphql 解析器函数获取 graphql 后端中的选定字段?【英文标题】:How to fetch selected fields in graphql backend using type-graphql resolver function? 【发布时间】:2021-02-08 17:36:25 【问题描述】:

我正在编写一个解析器,以使用 typescript 和 type-graphql 从 REST api 获取数据到 graphql 后端函数。我面临的问题是我从 API 获取所有道具的数据,但我只想返回前面的选定字段结尾。如何只返回选定的字段?

这是我的场景。我有反应应用程序作为前端。我会写所有 前端应用程序中的 graphql 查询。前端有 apollo 客户端 连接到后端的graphql。后端是编写的节点应用程序 打字稿。我的后端获取数据 从 rest api 并通过 apollo 服务器服务到前端。我们在后端使用 type-graphql

在这个问题中,我对后端有疑问。

我有以下类型(在后端定义为 personInfo.ts)

import  ObjectType, Field  from "type-graphql";

@ObjectType("PersonInfo")
export class PersonInfo 
  @Field( nullable: true ) firstName: string;
  @Field( nullable: true ) lastName: string;
  @Field( nullable: true ) registrationNo: string;
  @Field( nullable: true ) personCode: string;
  @Field( nullable: true ) personCapabilities: string;

我在解析器中使用上述类型,如下所示:(在后端定义为 personInfoResolver.ts)这个 graphql 解析器将使用下一部分编写的函数从 rest api 获取数据。该函数存在如下代码中所述的问题。

import  Query, Resolver, Arg  from "type-graphql";
import  PersonInfo  from "../types";
import  GetPersonInfo  from "./api/helpers";

@Resolver((of) => PersonInfo)
export class PersonInfoResolver 
  @Query((returns) => PersonInfo,  nullable: true )
  async PersonInfo(@Arg("serialNo") serialNo: string) 
    console.log(await GetPersonInfo(serialNo)); //<--this logs full object received from api with all the fields
    return await GetPersonInfo(serialNo); //when queried from graphql playground, i get null for selected values even if previous line prints all data
  

这是在 api helper 中获取数据的函数(在后端定义以连接到 api 并获取数据。)工作正常并从 rest api 获取所有对象。

export const GetPersonInfo = async (serialNo: string) => 
  var personInfoURL = "url" + serialNo;
  if (!serialNo) 
    return "";
  
  const response = await posApi
    .get(personInfoURL)
    .then(function (response) 
      return response.data;
    )
    .catch(function (error) );

  const data = await response;

  return data;
;

我正在使用 graphql 操场使用以下查询测试上述代码。

  
    PersonInfo(serialNo:"201123030")
     firstName
     lastName
     registrationNo
     registrationNo
     personCapabilities

 

【问题讨论】:

这个问题不完整,你的 graphql-query/mutation 在哪里? 或者,这就是您想知道的吗?如何编写graphql-schema-functions? @Joel 查询将在前端反应应用程序中。现在我正在节点中编写后端并使用graphql play ground进行测试。添加了有问题的查询 我会为你投票,这是一个很好的问题,虽然很混乱。请在下面查看我的答案,它会告诉你你想要什么。 你有机会看看我的解决方案吗? 【参考方案1】:

您的问题我不清楚,但我会尽力帮助您。

首先,您提供的 GraphQL 架构无效。

在操场上,你应该写:


    PersonInfo(serialNo: "201123030")  //not DetailsInfo
        firstName
        ...
    


鉴于您的实体看起来像这样

@Column()
@Field( nullable: true ) firstName: string;
@Column()
@Field( nullable: true ) lastName: string;
@Column()
@Field( nullable: true ) registrationNo: string;
@Column()
@Field( nullable: true ) personCode: string;
@Column()
@Field( nullable: true ) personCapabilities: string;

你的解析器看起来像这样

@Resolver(PersonInfo)
export class PersonInfoResolver 
  @Query(() => PersonInfo,  nullable: true )
  async PersonInfo(@Arg("serialNo") serialNo: string): Promise<PersonInfo> 
    return await GetPersonInfo(serialNo); //when queried from graphql playground, i get null for selected values even if previous line prints all data
  

我建议跑步

npm i -D @graphql-codegen @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/operations @graphql-codegen/typescript-react-apollo

它允许在您的项目中自动生成模式和类型安全。

在你的 react-project 的根目录中创建一个名为 codegen.yml 的文件(与 package.json 相同的位置)

overwrite: true
schema: "http://localhost:4000/graphql"
documents: "src/graphql/**/*.graphql"
generates:
  src/generated/graphql.tsx:
    plugins:
      - "typescript"
      - "typescript-operations"

src/* 中创建文件夹generated

或者,将上面的结构更改为您希望生成架构的任何位置。

你首先需要在src/graphql/queries/*中创建personinfo.query.graphql

(您也可以在此处创建另一个名为 src/graphql/mutations/ 的文件夹)

personinfo.query.graphql

query PersonInfo($serialNo: String!)  
     personInfo(serialNo: $serialNo) 
         firstName,
         lastName,
         registrationNo,
         personCode,
         personCapabilities  //or whatever subset of fields you want.
     

在您的控制台中输入:graphql-codegen --config codegen.yml,文件将被生成。现在打开graphql.tsx,看看它创造了什么。很整洁吧?

然后在你的 react-component 中做:

export const MyComponent: React.FC<> = () => 

    const [data] = usePersonInfoQuery(/*your serialNo here*/); //this function will have been generated now
    //then you have access to the fields you supplied to `personinfo.query.graphql`
    const fName = data.personInfo.firstName;
    const lName = data.personInfo.lastName;


【讨论】:

detailsinfo 只是复制粘贴错误。这是较早的详细信息。更新有问题。还添加了更多上下文信息。 @GauravChauhan 请检查我的解决方案,它向您展示了如何使用 apollo 在前端选择字段子集。

以上是关于如何使用 type-graphql 解析器函数获取 graphql 后端中的选定字段?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 type-graphql 定义对象类型

使用多个装饰器将 Type-GraphQL 与 Typegoose 相结合

Type-GraphQL 的参数错误 - 没有参数类型?

mikro-orm 使用 type-graphql 缓存数据

带有打字稿的graphql - @FieldResolver 在compiled-to-js type-graphql 中不起作用

获取请求的信息对象