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

Posted

技术标签:

【中文标题】GraphQL 中模式级和应用级错误的混合【英文标题】:Mixing of schema-level and app-level errors in GraphQL 【发布时间】:2016-10-06 12:57:37 【问题描述】:

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

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

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

这种行为对客户端确实没有帮助:它现在必须知道两个可能位置的错误(*** graphql 错误和突变有效负载中的应用程序错误)和两种可能的格式。这也意味着在所有模式级别的问题都得到修复之前,不会在 GraphQL 模式中表示其他格式错误的字段,这迫使用户经历多轮“修复错误,点击提交,得到另一个错误”。

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

【问题讨论】:

Github上的相关讨论:github.com/facebook/relay/issues/1141 【参考方案1】:

错误分类的问题

*** graphql 错误,以及变异负载中的应用程序错误

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

请参阅 Konstantin Tarkus 撰写的一篇简洁明了的文章:Validation and User Errors in GraphQL Mutations,我在此答案中采用了他的方法。

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

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

首先,在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
        
      ]
    
  ]

其次,将用户级错误作为一个单独的字段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, … ]

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

这种方法会丢失突变输入类型的自动验证。但是,验证不会受到影响,因为输入类型的验证逻辑可以放在单独的函数中。该函数将根据需要返回验证错误,最终将被放入突变负载的errors 字段中。

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

【讨论】:

【参考方案2】:

如果您使用的是 Apollo,您可以轻松地在 graphql 响应中多路复用错误数组,用于 graphql 错误和使用此包机器可读的自定义错误:

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

【讨论】:

以上是关于GraphQL 中模式级和应用级错误的混合的主要内容,如果未能解决你的问题,请参考以下文章

设计模式之观察者模式 DOM0级和DOM2级封装

将 GraphQL 模式拆分为 express-graphql 中不同模块的最佳方法?

完整的二叉树交换子级和父级错误

/graphql 处的递归错误。超出最大递归深度

打开graphql时couldnotfindconfig

如何从 GraphQL 生成 Dart - graphql 到 dart 生成器