Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
GraphQL响应类型/片段类型_Graphql_Apollo_Graphql Js_Graphql Tag - Fatal编程技术网

GraphQL响应类型/片段类型

GraphQL响应类型/片段类型,graphql,apollo,graphql-js,graphql-tag,Graphql,Apollo,Graphql Js,Graphql Tag,我在用graphql编写API时遇到了一些困难 我的api中的每个响应看起来都应该是相同的。 因此理想情况下,这将是graphql类型: type Response { success data { ... always different } errors { path message } } 但因为这里的数据字段总是不同的。每个变异/查询都应该有自己的响应类型(如果我正确理解graphql的话) 因此,对于登录,这是我使用transformer函

我在用graphql编写API时遇到了一些困难

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

type Response {
  success
  data {
    ... always different
  }
  errors {
    path
    message
  }
}
但因为这里的数据字段总是不同的。每个变异/查询都应该有自己的响应类型(如果我正确理解graphql的话)

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

type LoginResponse {
  success
  data {
    user
    token
  }
  errors {
    path
    message
  }
}
现在在我的前端,我想使用以下片段,因为这些属性总是出现在每个响应中

fragment Response on LoginResponse {
  success
  errors {
    path
    message
  }
}
这里已经展示了我的问题,通过一个片段,你也定义了它的父类型。所以我必须创建尽可能多的独立片段作为独立的响应类型


有没有人可能已经在这方面遇到了困难,或者是否有一个我没有看到的最佳实践一般来说,当您有一个字段可以解析为多种类型中的一种时,您可以使用联合。如果这些类型共享一个或多个字段,则可能需要使用接口

模式中常见的模式是
节点
接口。您可以使用查询按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!
}
这里,
节点
可以是
Foo
,因此,如果我们要为
节点
编写一个片段,它可能看起来像这样:

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替代,以达到相同的效果:

union SomeUnion = Foo | Bar
因此,为了减少前端代码中的一些重复,您可以将每个
结果
类型设置为一个接口,或者更好的做法是,将一个
结果
类型与
数据
组合。不幸的是,接口或联合都不能处理标量或列表,如果对于某些查询,
data
应该是标量或列表,这会使事情变得复杂

然而,在一天结束时,一开始就用这种方式构建模式可能是不可取的。有很多很好的理由可以避免这种结构:

  • GraphQL已经将查询结果作为JSON对象返回,其中包含
    数据
    错误
    属性
  • 在GraphQL
    数据
    中返回错误需要额外的逻辑来捕获和格式化错误,而不是在任何地方抛出错误并让GraphQL为您处理错误报告
  • 您将无法捕获验证错误,因此可能会在两个位置出现错误—在
    errors
    数组内部和
    data.errors
    内部。这也意味着您的客户机需要在两个位置查找错误,以进行正确的错误处理
  • GraphQL是专门为允许部分解析响应而设计的。这意味着,即使响应的某些部分出错并未能解决,其他部分仍可能被解决并作为响应的一部分返回。这意味着响应“成功”的概念在GraphQL中并不适用。如果您确实需要一个
    success
    字段,那么最好在查询解析后使用
    formatResponse
    之类的方法将其添加到响应对象中
  • 这将大大简化遵守约定的过程,并按照以下思路构建您的模式:

    type Query {
      login: LoginResponse
    }
    
    type LoginResponse {
      token: String
      user: User
    }
    
    实际响应仍将包括
    数据
    错误

    {
      "data": {
        "login": {
          "token": "",
        }
      },
      "errors": []
    }
    

    如果您甚至需要使用片段,那么每种类型仍然需要一个片段,但是片段之间的重复会明显减少。

    关于如何处理错误的好视频(与此问题相关):

    这正是我想要的解释类型。谢谢你,伙计!重构我的响应并尝试自动错误。我以前也见过工会,但不知道你也可以在这上面分裂。