GraphQL响应类型/片段挣扎

时间:2018-12-13 01:29:28

标签: graphql apollo graphql-js graphql-tag

我在用graphql编写API时有些挣扎。

我的api中的每个响应都应该看起来有些相同。 因此理想情况下,这应该是graphql类型:

type Response {
  success
  data {
    ... always different
  }
  errors {
    path
    message
  }
}

但是因为这里的数据字段总是不同的。每个突变/查询都应具有自己的响应类型(如果我正确理解了graphql)。

因此,对于登录,这是我使用转换器函数创建的类型:

type LoginResponse {
  success
  data {
    user
    token
  }
  errors {
    path
    message
  }
}

现在在我的前端,我想使用以下片段,因为这些属性始终存在于每个响应中。

fragment Response on LoginResponse {
  success
  errors {
    path
    message
  }
}

因此,我遇到的问题已经在此处显示,您还可以通过片段定义其父类型。因此,我必须创建与单独的响应类型一样多的单独的片段。

有人可能已经为此感到挣扎了吗?还是我没有看到针对这种情况的最佳实践?

2 个答案:

答案 0 :(得分:1)

通常,当您拥有可以解析为多种类型之一的字段时,可以使用联合。如果这些类型共享一个或多个字段,则可能要使用一个Interface。

在模式中看到的常见模式是Node接口的想法。您可能会执行查询以按ID提取节点,例如:

type Query {
  node(id: ID!): Node
}

interface Node {
  id: ID!
}

type Foo implements Node {
  id: ID!
  foo: String!
}

type Bar implements Node {
  id: ID!
  bar: Int!
}

在这里,Node可以是FooBar,所以如果我们要为Node编写一个片段,它可能看起来像这样:< / p>

fragment NodeFields on Node {
  id # id is part of the interface itself
  ... on Bar {
    bar # fields specific to Bar
  }
  ... on Foo {
    foo # fields specific to Foo
  }
}

如果没有共享字段,则可以使用联合来达到相同的效果:

union SomeUnion = Foo | Bar

因此,为减轻前端代码中的某些重复,您可以使每个Result类型成为一个接口,或者更好的是,将单个Result类型与{{1 }}成为工会。不幸的是,接口或联合都不能与标量或列表一起使用,如果data被认为是某些查询的标量或列表,则会使情况变得复杂。

但是,到最后,不建议您首先以这种方式构造架构。有许多避免这种结构的充分理由:

  1. GraphQL已经作为具有datadata属性的JSON对象返回查询结果。
  2. 在GraphQL errors内部返回错误将需要附加的逻辑来捕获和格式化错误,而不是能够在任何地方抛出错误并让GraphQL为您处理错误报告。
  3. 您将无法捕获验证错误,因此可能会在两个地方出现错误–在data数组内部和errors内部。这也意味着您的客户需要在两个位置查找错误以进行正确的错误处理。
  4. GraphQL经过专门设计,可以部分解决响应。这意味着即使响应的某些部分出错并无法解决,其他部分仍可能会被解决并作为响应的一部分返回。这意味着响应“成功”的概念在GraphQL中并没有真正应用。如果您绝对需要一个data.errors字段,那么在查询解析后,最好使用success之类的东西将其添加到响应对象中。

遵循约定将使事情变得更加简单,并按照以下方式构建架构:

formatResponse

实际响应仍将包括type Query { login: LoginResponse } type LoginResponse { token: String user: User } data

errors

即使您甚至需要使用片段,每种类型仍然需要一个片段,但是片段之间的重复将大大减少。

答案 1 :(得分:0)

有关如何处理错误(与此问题相关)的优质视频:https://www.youtube.com/watch?v=-wRXk_QZ3Ko