当前位置: 首页 > 知识库问答 >
问题:

解析Graphql中的类型

后星河
2023-03-14

GraphQL中有几个地方需要解析类型,而不仅仅是类型中的字段

后端API-

  • /users-用户列表-最少信息-姓名、id

构建一个架构来执行以下查询

query a {
  users {
    age # some detail info
  }
  foo {
    owner {
      location # some detail info
    }
  }
}

模式可以如下-

type Query {
  users: [User]
  foo: Foo
}
type Foo {
  owner: User
}
type User {
  id: ID
  age: Int
  location: String
}

上述模式中的解析器需要在两个不同的地方包含/处理用户详细信息获取调用。1.用户列表-Query.users和2.Query.foo.owner。必须记住处理这种类型,其中您只有一个用户ID将其转换为实际用户。

在撰写本文时,GraphQL支持InterfaceUnion上的解析类型。不可能为整个Type指定解析器-只有Type中的字段可以具有解析器。因此,如果可以解析GraphQL中的类型,这将使其实现更简单。

由于只能解析类型中的字段,因此可以创建一个额外的类型,并在解析程序中维护该字段在类型中的处理,并且该字段位于一个位置。但是现在,查询比以前更深了一层。

query b {
  users {
    details {
      age
    }
  }
  foo {
    owner {
      details {
        location
      }
    }
  }
}

由于无法在GraphQL中解析类型枚举面临相同的问题。如果API响应中有一个特殊字符,并且字段是一个枚举,请记住在使用此枚举的所有位置处理它,或者创建一个额外的类型来表示此枚举。

我用ApolloGraphQL为所有这些案例创建了一个最小的修改-https://github.com/boopathi/graphql-test-1

  1. 模式/语言不应该支持指定如何处理特定类型/为类型指定解析器,而不仅仅是类型中的字段吗?若否,原因为何

共有1个答案

田兴旺
2023-03-14

你说得对-这在GraphQL中肯定有点奇怪。本质上,由于解析器的工作方式,负责获取正确数据的是您来自的类型,而不是您将要访问的类型。

这种方法有优点也有缺点。您完全可以想象GraphQL的一个实现,其中父对象只返回一个ID,然后每个类型都有一个解析器,知道如何获取细节。我认为这在某些情况下肯定会更好。

下面是我们目前建议如何构建代码以避免这种耦合:

  1. 为不同的后端数据源和对象类型定义模型类或存储库对象
  2. 在解析器中使用这些,而不是直接访问数据库

为了实现穷人的依赖注入,我们将它们放到服务器的上下文中。当你把它们放在一起时,看起来是这样的:

模式:

# Information about a GitHub repository submitted to GitHunt
type Entry {
  # Information about the repository from GitHub
  repository: Repository!
  # The GitHub user who submitted this entry
  postedBy: User!
  ...

解析程序:

export const resolvers = {
  Entry: {
    repository({ repository_name }, _, context) {
      return context.Repositories.getByFullName(repository_name);
    },
    postedBy({ posted_by }, _, context) {
      return context.Users.getByLogin(posted_by);
    },
    ...

您可以在GitHunt-API示例应用程序中的整个服务器上下文中看到这一点。

基本上,这种方法将解析器用作调用底层业务逻辑的薄包装器,就像路由器一样。这与当前关于Facebook和其他网站服务器的文献是一致的。

 类似资料:
  • 我试图通过构建一个具有以下模式的服务器来熟悉Graphql: 并映射到以下数据: 在编写解析器时,我注意到很多样板代码——我必须为每个持有外键的对象成员编写概念上相同的字段解析器。 有没有办法通过ID创建类型解析器?例如,字段或查询总是由

  • 我正在这个名为Wertik JShttps://github.com/ilyaskarim/wertik-js库上工作,以使GraphQL Rest API更容易,在解析器中,当我控制台日志时,它显示未定义。对于每个模块,我都创建了动态解析器,让使用这个库的开发人员更容易。 行:https://github.com/ilyaskarim/wertik-js/blob/ec813f49a14ddd6

  • 如果我有模式: 和一个解析器: 和两个可能的查询。问题#1: 和查询#2: 是否可以优化冲突解决程序,使查询#1 readAllPosts仅从数据库中提取标题,而查询#2则同时提取标题和lotsofdata? 我查看了parent、args、context和info参数,但看不到任何指示解析器是否被调用以响应像#1或#2这样的查询的内容。

  • 我花了相当多的时间阅读GraphQL教程,但不幸的是,它们似乎没有涵盖足够的深度,我无法理解。我真的很感谢你对这个现实世界的例子的帮助。 在示例中,查询位于解析器对象的根;我可以让它在单级查询中正常工作。但是,当我尝试解析嵌套查询时,嵌套解析程序从未被调用。让我非常困惑的是,我发现graphql网站上没有发布的每一个教程都放在一个查询对象中,并将它们的查询嵌套在下面,而不是根级别。 考虑以下模式:

  • 您好,我正在尝试将我的graphql查询格式化为json请求,如下所示。我想以字符串形式传递id,值为“3”,当我将其作为json请求发送时,graphql会以错误的形式拒绝。我如何解决这个问题? edit1中添加的架构:`#公开指定此标量行为的URL。指令@specifiedBy( URL: String!)on|SCALAR 架构{query:RootQueryType mutation:mu

  • 我一直在阅读graphQL文档,发现它们以两种方式解释了graphQL服务器的实现:一种是使用graphQL瑜伽,这是一种功能齐全的graphQL服务器,另一种是使用graphQL、express graphQL和express。在这两种情况下,我们在创建服务器实例时传递模式和解析器函数。 但是解析器函数的实现是不同的。使用graphql瑜伽时,解析器函数提供了4个参数,其中包含有关父对象、接收的