首页 文章

在GraphQL中混合模式级和应用级错误

提问于
浏览
4

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

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

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

这种行为对客户来说真的没有用处:它现在必须知道两个可能位置的错误(顶级graphql错误,以及突变有效负载中的应用程序错误)以及两种可能的格式 . 这也意味着在修复所有架构级问题之前,不会报告其Graphitive架构中未表示格式错误的其他格式错误的字段,从而迫使用户经历多轮“修复错误,点击提交,得到另一个错误“ .

这个问题的标准解决方案是什么?在客户端上进行验证(在这种情况下非常复杂)?削弱架构以便在应用程序层对所有相关验证进行分组?

2 回答

  • 5

    错误分类的问题

    顶级graphql错误,以及变异有效负载中的应用程序错误

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

    请参阅Konstantin Tarkus关于此的一篇精美而简洁的文章:Validation and User Errors in GraphQL Mutations,我在这个答案中遵循了他的方法 .

    一个不那么标准但又有意义的解决方案

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

    首先, system-level errors 位于mutation response的顶级字段 errors 中:

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

    其次,将 user-level errors 作为单独的字段 errors 放入变异有效载荷中 . 上述文章的例子:

    {
      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, … ]
    

    上述方法使客户端能够查找 user errors in a defined format in a single place - 变异有效负载的 errors 字段 . 它还允许客户端一起接收所有错误 .

    这种方法失去了对变异的自动验证's input type. However, validation is not compromised as the input type'的验证逻辑可以放在一个单独的函数中 . 此函数将根据需要返回验证错误,最终将放入突变有效负载的 errors 字段 .

    顺便说一下,感谢写得好的问题!

  • 0

    如果您正在使用Apollo,您可以轻松地在graphql响应中复用errors数组,以解决graphql错误和使用此程序包可读取的自定义错误:

    https://github.com/thebigredgeek/apollo-errors

相关问题