在GraphQL中混合模式级别和应用程序级别的错误 [英] Mixing of schema-level and app-level errors in GraphQL

查看:68
本文介绍了在GraphQL中混合模式级别和应用程序级别的错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在graphql API之上构建新应用程序时,我们遇到了以下问题:

While building a new application on top of a graphql API we have run into the following problem:

我们有一个突变,其输入字段的类型是具有自己的验证规则的自定义标量(在这种情况下,输入是格式正确的电子邮件地址).

We have a mutation with an input field whose type is a custom scalar with its own validation rules (in this case that the input is a well-formed email address).

在客户端上,应用程序的用户填写了许多字段,然后点击提交.当前,电子邮件地址的验证由GraphQL层处理,如果突变失败并出现顶级错误,则中止突变.变异处理所有 other 字段的验证,并在变异有效载荷中返回应用程序级错误.在这种情况下,其他验证不能直接在模式中表示,因为它们涉及相互依赖的字段.

On the client, the user of the app fills in a bunch of fields and hits submit. Currently, validation of the email address is handled by the GraphQL layer and aborts the mutation if it fails with a top-level error. Validation of all other fields is handled by the mutation, returning app-level errors in the mutation payload. The other validations in this case cannot be represented directly in the schema since they involve inter-dependent fields.

此行为对客户端确实没有帮助:现在,它必须知道两个可能位置(顶级graphql错误以及突变有效载荷中的应用程序错误)和两种可能格式的错误.这也意味着在解决了所有架构级别的问题之前,不会报告GraphQL架构中未表示格式错误的其他格式错误的字段,从而迫使用户经历多轮修复错误,点击提交,出现另一个错误".

This behaviour is really unhelpful for the client: it now has to know about errors in two possible locations (top-level graphql errors, and the application errors in the mutation payload) and in two possible formats. It also means that other malformed fields whose malformed-ness is not represented in the GraphQL schema will not be reported until all the schema-level issues have been fixed, forcing the user to go through multiple rounds of "fix the error, hit submit, get another error".

此问题的标准解决方案是什么?将验证(在这种情况下非常复杂)放在客户端上吗?为了对应用程序层中的所有相关验证进行分组而对模式进行弱化吗?

What is the standard solution to this problem? Putting validations (quite complex in this case) on the client? Weakening the schema in order to group all relevant validations at the application layer?

推荐答案

错误分类问题

顶级graphql错误以及突变有效载荷中的应用错误

top-level graphql errors, and the application errors in the mutation payload

您在模式级别错误和应用程序级别错误之间进行区分是基于GraphQL类型和变异实现.客户端应用程序通常期望更高的错误抽象级别,即,它需要区分用户错误和系统错误.这样,它可以将系统错误掩盖为内部错误",并在必要时显示用户错误.开发人员还可以检查系统错误集.

The distinction that you made between schema-level and application level errors is based on GraphQL type and mutation implementation. A client-side application usually expects a higher abstraction level of errors, i.e., it needs to distinguish user errors and system errors. That way it can mask the system errors as "internal error" and present the user errors as necessary. The developer also can inspect the set of system errors.

请参见Konstantin Tarkus的一篇简洁明了的文章: GraphQL突变中的验证和用户错误,我在此答案中遵循的方法.

See a nice and concise article by Konstantin Tarkus on this: Validation and User Errors in GraphQL Mutations, whose approach I have followed in this answer.

据我所知,没有特定的标准方法.但是,您可以尝试以下方法.

To the best of my knowledge, there is no particular standard approach. However, you can try out the following approach.

首先,在errors 中具有系统级错误>变异响应:

First, having system-level errors in the top-level field errors of mutation response:

{
  "data": {
    "viewer": {
      "articles": {
        "edges": [
          {
            "node": {
              "title": "Sample article title",
              "tags": null
            }
          }
        ]
      }
    }
  },
  "errors": [
    {
      "message": "Cannot read property 'bar' of undefined",
      "locations": [
        {
          "line": 7,
          "column": 11
        }
      ]
    }
  ]
}

第二,将用户级错误作为单独的字段 errors 放入突变有效载荷中.提到的文章中的示例:

Second, putting user-level errors as a separate field errors in mutation payload. Example from the mentioned article:

{
  data: {
    user: null,
    errors: [
      '',
      'Failed to create a new user account.',
      'email',
      'User with this email address was already registered.',
    ]
  }
}
// The errors field is just an array of strings that follows this pattern —
// [argumentName1, errorMessage1, argumentName2, errorMessage2, … ]

以上方法使客户端可以在单个位置查找定义格式的用户错误-突变有效载荷的 errors 字段.它还允许客户端一起接收所有错误.

The above approach enables the client to look for user errors in a defined format in a single place - the errors field of mutation payload. It also allows the client to receive all errors together.

这种方法无法自动验证突变的输入类型.但是,验证不会受到影响,因为可以将输入类型的验证逻辑放在单独的函数中.此函数将根据需要返回验证错误,最终将其放置在变异有效载荷的 errors 字段中.

This approach loses automatic validation of the mutation's input type. However, validation is not compromised as the input type's validation logic can be put in a separate function. This function will return validation errors as necessary, which will eventually be put in mutation payload's errors field.

顺便说一句,谢谢你写的很好的问题!

By the way, thanks for the well-written question!

这篇关于在GraphQL中混合模式级别和应用程序级别的错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆