GraphQL.Net - 防止空数据突变异常
GraphQL.Net - prevent null data on mutation exception
使用 GraphQL.NET,我定义了一个不可为 null 的 return 类型(例如 LoginPayload
),用于这样的突变:
type MyMutation {
login(input: LoginInput!): LoginPayload!
}
在 C# 中,它看起来像这样:
FieldAsync<NonNullGraphType<LoginPayloadType>>(
"login",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<LoginInputType>> { Name = "input" }),
resolve: async context =>
{
//...
});
根据此模式定义,客户端希望响应数据永远不会为空。但是,如果在解析器中抛出异常,GraphQL.NET 会这样响应:
{
"data": {
"login": null
},
"errors": [
{
"message": "GraphQL.ExecutionError: some exception thrown",
...
}
]
}
如何配置 GraphQL.Net 以在出现错误时排除 data
属性,因此它看起来像这样?
{
"errors": [
{
"message": "GraphQL.ExecutionError: some exception thrown",
...
}
]
}
如果这是您实际看到的行为,那么这是一个错误,因为这不是应该发生的事情 according to the spec。
Since Non-Null type fields cannot be null, field errors are propagated to be handled by the parent field. If the parent field may be null then it resolves to null, otherwise if it is a Non-Null type, the field error is further propagated to it’s parent field... If all fields from the root of the request to the source of the field error return Non-Null types, then the "data" entry in the response should be null.
此问题已在 GraphQL.NET 3.5 预发布版中修复。
示例 1:NonNullGraphType
查询字段:
Field<NonNullGraphType<WidgetType>>(
"exception",
resolve: context =>
{
throw new ExecutionError("Something went wrong!");
}
);
版本 3.4 响应:
{
"data": {
"exception": null
},
"errors": [
{
"message": "Something went wrong!",
...
}
]
}
版本 3.5 响应:
{
"errors": [
{
"message": "Something went wrong!",
...
}
],
"extensions": {
...
}
}
示例 2:可为空
查询字段:
Field<WidgetType>(
"exceptionAndNullable",
resolve: context =>
{
throw new ExecutionError("Something went wrong!");
}
);
版本 3.4 响应:
{
"data": {
"exceptionAndNullable": null
},
"errors": [
{
"message": "Something went wrong!",
"...
}
]
}
版本 3.5 响应:
{
"data": {
"exceptionAndNullable": null
},
"errors": [
{
"message": "Something went wrong!",
...
],
"extensions": {
...
}
}
请注意,示例 1 中的 data
在版本 3.5 中不再返回,而在示例 2 中,各版本之间的响应基本没有变化。
使用 GraphQL.NET,我定义了一个不可为 null 的 return 类型(例如 LoginPayload
),用于这样的突变:
type MyMutation {
login(input: LoginInput!): LoginPayload!
}
在 C# 中,它看起来像这样:
FieldAsync<NonNullGraphType<LoginPayloadType>>(
"login",
arguments: new QueryArguments(
new QueryArgument<NonNullGraphType<LoginInputType>> { Name = "input" }),
resolve: async context =>
{
//...
});
根据此模式定义,客户端希望响应数据永远不会为空。但是,如果在解析器中抛出异常,GraphQL.NET 会这样响应:
{
"data": {
"login": null
},
"errors": [
{
"message": "GraphQL.ExecutionError: some exception thrown",
...
}
]
}
如何配置 GraphQL.Net 以在出现错误时排除 data
属性,因此它看起来像这样?
{
"errors": [
{
"message": "GraphQL.ExecutionError: some exception thrown",
...
}
]
}
如果这是您实际看到的行为,那么这是一个错误,因为这不是应该发生的事情 according to the spec。
Since Non-Null type fields cannot be null, field errors are propagated to be handled by the parent field. If the parent field may be null then it resolves to null, otherwise if it is a Non-Null type, the field error is further propagated to it’s parent field... If all fields from the root of the request to the source of the field error return Non-Null types, then the "data" entry in the response should be null.
此问题已在 GraphQL.NET 3.5 预发布版中修复。
示例 1:NonNullGraphType
查询字段:
Field<NonNullGraphType<WidgetType>>(
"exception",
resolve: context =>
{
throw new ExecutionError("Something went wrong!");
}
);
版本 3.4 响应:
{
"data": {
"exception": null
},
"errors": [
{
"message": "Something went wrong!",
...
}
]
}
版本 3.5 响应:
{
"errors": [
{
"message": "Something went wrong!",
...
}
],
"extensions": {
...
}
}
示例 2:可为空
查询字段:
Field<WidgetType>(
"exceptionAndNullable",
resolve: context =>
{
throw new ExecutionError("Something went wrong!");
}
);
版本 3.4 响应:
{
"data": {
"exceptionAndNullable": null
},
"errors": [
{
"message": "Something went wrong!",
"...
}
]
}
版本 3.5 响应:
{
"data": {
"exceptionAndNullable": null
},
"errors": [
{
"message": "Something went wrong!",
...
],
"extensions": {
...
}
}
请注意,示例 1 中的 data
在版本 3.5 中不再返回,而在示例 2 中,各版本之间的响应基本没有变化。