【问题标题】:How to fetch selected fields in graphql backend using type-graphql resolver function?如何使用 type-graphql 解析器函数获取 graphql 后端中的选定字段?
【发布时间】: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进行测试。添加了有问题的查询
  • 我会为你投票,这是一个很好的问题,虽然很混乱。请在下面查看我的答案,它会告诉你你想要什么。
  • 你有机会看看我的解决方案吗?

标签: node.js typescript graphql typegraphql


【解决方案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 在前端选择字段子集。
猜你喜欢
  • 1970-01-01
  • 2018-06-08
  • 2018-06-16
  • 2017-06-24
  • 2020-10-07
  • 2021-04-19
  • 2020-08-19
  • 2021-05-02
相关资源
最近更新 更多