通常,您应该避免在没有警告的情况下删除字段,以避免您描述的确切情况。
随着架构的发展,一些不再需要的字段并不少见。例如,我们可以选择添加另一个字段并鼓励客户转换为使用该字段,而不是对特定字段进行重大更改(从可为空的返回类型变为不可为空的返回类型、添加必需的参数等)反而。在这种情况下,我们希望最终删除原始字段。最安全的方法是首先弃用该字段。使用 SDL,我们可以使用指令来做到这一点:
fieldA: String @deprecated(reason: "Use fieldB instead!")
一段时间后,您可以完全删除该字段。您等待删除该字段的时间取决于您的团队以及您就处理已弃用的字段所传达的期望。例如,您可能会发现设置截止日期很有帮助,届时所有客户端都应该停止使用任何已弃用的字段。只要您的客户团队有足够的带宽来处理此类技术债务,这种方法就很有效。
不推荐使用的字段的解析器可以更改为返回空值(如果字段本身可以为空)或一些最小的模拟数据。这可以防止进行不必要的 API 或数据库调用,同时仍确保客户端请求不会导致错误。
在您的问题的上下文中,这意味着您可能应该避免回滚到以前的版本,而是按照上面概述的过程来处理您要删除的字段。
或者,您可以考虑版本控制。GraphQL 通常回避版本控制的概念。正如官方网站解释的那样:
为什么大多数 API 都有版本?当对从 API 端点返回的数据的控制有限时,任何更改都可以被视为重大更改,而重大更改需要新版本。如果向 API 添加新功能需要新版本,那么在经常发布和拥有许多增量版本与 API 的可理解性和可维护性之间会出现权衡。
相比之下,GraphQL 仅返回明确请求的数据,因此可以通过新类型和这些类型上的新字段添加新功能,而不会造成重大更改。这导致了一种常见的做法,即始终避免中断更改并提供无版本 API。
考虑到这一点,通过提供来自不同端点的不同模式,仍然可以使用 GraphQL 实现版本控制。虽然走这条路代价高昂且通常没有必要,但它可能是您和您的团队的正确解决方案,特别是如果您预计将来必须进行类似的回滚。