【问题标题】:Graphql Schema update rollbackGraphql Schema 更新回滚
【发布时间】:2018-12-18 15:19:58
【问题描述】:

我们正在将我们的一些 API 迁移到 graphql,并想知道如何处理已部署包 (Schema) 的回滚以及相同的最佳实践。

更具体地说,假设我们有一个包含 3 个字段的模式 S,然后我们添加了第 4 个字段“A”。现在由于某种原因,我们不能继续使用这个包和字段“A”。所以我们必须执行包的回滚,以便现在模式没有字段“A”。

现在有些消费者可能会要求输入“A”字段,他可能会收到错误消息。我们当然可以要求我们的客户进行更新,但是在一段时间内我们可能会请求失败。

我们如何处理这种情况,特别是几个小时或一天内的紧急回滚?

【问题讨论】:

    标签: scala graphql apollo sangria


    【解决方案1】:

    一般来说,您应该避免在没有警告的情况下删除字段,以避免您描述的确切情况。

    随着架构的发展,某些字段不再需要的情况并不少见。例如,我们可以选择添加另一个字段并鼓励客户过渡到使用该字段,而不是对特定字段进行重大更改(从可为空的返回类型转变为不可为空的返回类型、添加必需的参数等)反而。在这种情况下,我们希望最终删除原始字段。最安全的方法是首先弃用该字段。使用 SDL,我们可以使用指令来做到这一点:

    fieldA: String @deprecated(reason: "Use fieldB instead!")
    

    一段时间后,您可以完全删除该字段。您等待删除该字段的时间取决于您的团队以及您就处理已弃用的字段所传达的期望。例如,您可能会发现设置截止日期很有帮助,届时所有客户端都应该停止使用任何已弃用的字段。只要您的客户团队有足够的带宽来处理此类技术债务,这种方法就会很有效。

    可以更改已弃用字段的解析器以返回空值(如果字段本身可以为空)或一些最小的模拟数据。这可以防止进行不必要的 API 或数据库调用,同时仍确保客户端请求不会导致错误。

    就您的问题而言,这意味着您可能应该避免回滚到以前的版本,而是按照上面概述的流程处理您要删除的字段。

    或者,您可以考虑版本控制。 GraphQL 通常回避版本控制的概念。正如官方网站解释的那样:

    为什么大多数 API 都有版本?当对从 API 端点返回的数据的控制有限时,任何更改都可以被视为重大更改,而重大更改需要新版本。如果向 API 添加新功能需要新版本,则需要在经常发布和拥有许多增量版本与 API 的可理解性和可维护性之间进行权衡。

    相比之下,GraphQL 仅返回明确请求的数据,因此可以通过新类型和这些类型上的新字段添加新功能,而不会造成重大更改。这导致了一种常见的做法,即始终避免中断更改并提供无版本 API。

    考虑到这一点,通过提供来自不同端点的不同模式,仍然可以使用 GraphQL 实现版本控制。虽然走这条路代价高昂且通常没有必要,但它可能是您和您的团队的正确解决方案,特别是如果您预计将来必须进行类似的回滚。

    【讨论】:

    • 感谢您的建议。我已经完成了弃用字段的最佳实践,您的回答也提供了很好的信息,但我更担心一些紧急回滚。假设我们部署了,在几个小时内我们意识到事情已经出了问题,现在我们回滚了。休息时,我们只是忽略请求模型中不存在的请求字段,这可能不是最好的方法,但仍然保持我们的 API 和业务运行。在 Graphql 的情况下,我们最终会得到失败的响应,这将是业务连续性的噩梦。
    • 即使使用 REST,您也可能会遇到同样的问题。例如,如果您设置了请求验证,则将查询参数添加到端点然后进行回滚也会导致客户端请求爆炸。
    • 如果您设置了开发和/或登台环境,集成测试应该会发现任何主要问题。根据经验,当我们在后端出现严重错误时,几乎总是在开发环境中发现,因为客户团队开始将架构更改集成到他们的应用程序中。如果有任何错误进入生产环境,它们的影响相当小,当然不保证回滚到早期版本。
    • 我同意这一点,因为如果您必须在生产中进行回滚,那可能会突出您的整个开发/QA 工作流程中的一些缺陷。
    • 是的,我想知道这个关于没有版本的说法。弃用是一种好方法,但如果您有较旧的客户端并且想要更新或删除某些内容,仍然不会改变事实。我对无版本的定义必须包括新旧客户端,如果不特别注意更改,我只是看不出这是怎么可能的。
    【解决方案2】:

    你不能用 GraphQL 做任何事情。因为您需要在 GraphQL 类型系统中存在该字段。可能有可用的库,可让您指定字段应该是否出现在查询中。但是,没有办法在查询中允许不存在的字段。

    但您可以选择蓝绿部署策略。在此策略中,您可以同时运行两个版本。

    假设:绿色有字段A的版本,蓝色没有字段A的版本。因此,当您的客户更新时,他们会开始请求 Blue 版本。一旦您的所有客户端都更新完毕,请关闭 Green(with Field A

    【讨论】:

      猜你喜欢
      • 2021-03-03
      • 2018-09-07
      • 2020-08-17
      • 2016-05-06
      • 2021-03-28
      • 1970-01-01
      • 2018-07-17
      • 2020-12-08
      • 2017-09-25
      相关资源
      最近更新 更多