我正在考虑实现同时包含错误和数据的graphql响应的方法。
是否可以在不创建包含error
的类型的情况下这样做?
例如
突变addMembersToTeam(membersIds: [ID!]! teamId: ID!): [Member]
将成员添加到某个团队。假定使用以下membersIds
:[1, 2, 3]
来调用此突变。
具有ID 1和2的成员已经在团队中,因此必须抛出一个错误,即不能添加这些成员,但是应该添加ID 3的成员,因为他不在团队中。
我当时正在考虑使用formatResponse
,但似乎那里没错。
是否可以在不将错误字段添加到返回类型的情况下解决此问题?
答案 0 :(得分:1)
是否可以在不将错误字段添加到返回类型的情况下解决此问题?
不幸的是,没有。
解析器可以返回数据,也可以返回null并引发错误。它不能同时做到。为了澄清,有可能得到部分响应和一些错误。一个简单的例子:
const typeDefs = `
type Query {
foo: Foo
}
type Foo {
a: String
b: String
}
`
const resolvers = {
Query: {
foo: () => {},
}
Foo: {
a: () => 'A',
b: () => new Error('Oops!'),
}
}
在此示例中,查询foo
上的两个字段都将产生以下响应:
{
"data": {
"foo": {
"a": "A",
"b": null
}
},
"errors": [
{
"message": "Oops",
"locations": [
{
"line": 6,
"column": 5
}
],
"path": [
"foo",
"b"
]
}
]
}
通过这种方式,可以同时发送数据和错误。但是您不能在同一字段中这样做,就像您的问题一样。有两种解决方法。如您所指出的,您可以将错误作为响应的一部分返回,通常是这样做的。然后,您可以使用formatResponse
,遍历结果数据,提取任何错误,并将其与其他GraphQL错误合并。不是最佳选择,但是它可以使您获得所需的行为。
另一种选择是修改突变,使其采用单个memberId。然后,您可以为要添加的每个ID请求单独的突变:
add1: addMemberToTeam(memberId: $memberId1 teamId: $teamId): {
id
}
add2: addMemberToTeam(memberId: $memberId2 teamId: $teamId): {
id
}
add3: addMemberToTeam(memberId: $memberId3 teamId: $teamId): {
id
}
这在处理客户端方面可能会比较棘手,并且效率当然较低,但同样可能使您获得预期的行为。
答案 1 :(得分:0)
如果您考虑合并GraphQL错误-在Apollo中有一种解决方法。
您需要使用errorPolicy
。 Link for documentation
将策略设置为all
可以帮助您通知用户该错误,并同时拥有尽可能多的数据。
无:这是与Apollo Client 1.0匹配的默认策略 工作了。任何GraphQL错误都与网络错误相同,并且 从响应中忽略任何数据。
忽略:忽略可让您 读取与GraphQL错误一起返回的所有数据,但不读取 保存错误或将错误报告给您的用户界面。
全部:使用全部策略 是在仍然发生时通知用户潜在问题的最佳方法 显示来自服务器的尽可能多的数据。它保存两个数据 并将错误导入Apollo缓存,以便您的UI可以使用它们。
但是根据最佳实践,您不应以这种方式进行操作。 这是great article,用于处理GraphQL中的错误。
因此,更可取的方法是添加"errors"
字段作为响应的一部分,并以js代码进行处理。
答案 2 :(得分:0)
我们可以通过使用联合来实现。我建议您浏览精彩的文章Handling GraphQL errors like a champ
示例:
Mutation part: We can return the union type for the response & capture the result according to types.
type MemberType {
id: ID!
name: String!
}
type ErrorType {
id: ID!
message: String!
statusCode: Int!
}
union UserRegisterResult = MemberType | ErrorType;
addMembersToTeam(membersIds: [ID!]! teamId: ID!): [MemberResult!]!
Response:
addMembersToTeam(membersIds: [ID!]! teamId: ID!): {
...on MemberType{
id,
name,
}
...on ErrorType{
id,
message,
statusCode,
}
}