【问题标题】:What is the best way to maintain previous versions of an API in Azure?在 Azure 中维护以前版本的 API 的最佳方法是什么?
【发布时间】:2020-05-03 03:55:53
【问题描述】:

我的目标是让以前的版本不可变:它们的定义和功能不应该改变。 API 使用基于 .NET 4.7.2(依赖原因)的 ASP.NET Core 构建,并作为 Azure 应用服务托管。

最好是,我不想通过添加“版本知识”来弄乱我的代码。此外,如果版本可以托管在相同的基本 URL 下,那也很好。

我的研究:

  1. ASP.NET API Versioning

这样,您就可以完全控制应用程序中的版本控制。但是当新版本发布时,所有旧版本也会更新,因此可以更改。这意味着您不能更改任何现有函数,而必须创建新版本,like Scott does in URL PATH SEGMENT VERSIONING

  1. Azure Deploymentslots

正如文档所解释的,这应该用于暂存。但是,这也可以用于“存储”您的版本,因为每个部署槽都是托管的,彼此之间没有任何关系。

  1. Virtual Applications

将版本托管为虚拟应用程序也是一种选择。但是,应用服务的所有设置都在这些虚拟应用程序之间共享。这意味着在更改任何设置时,这将影响每个版本。

  1. Azure Web App for Containers

我对此的了解有限,但从我所阅读的内容来看,这也是一种选择。根据您的应用程序版本创建图像,将这些图像上传到Azure Container Registery。然后使用这些图像为每个版本创建一个应用服务。

【问题讨论】:

  • 在提供答案之前,我想澄清一下您的意思:"...当发布新版本时,所有旧版本也会更新,因此可以改变。这意味着你不能改变任何现有的函数,而必须创建新的版本......” 你如何实现隔离的实现细节可以有很大的不同。肯定有办法让以前版本的代码完全不受影响。旧版本只有在更改它们时才会更改。
  • 我的意思是,通过 API 版本控制,只要您保持代码不变,以前的版本就会包含在 API 中。但是为了实现不变性,不应更改以前版本使用的所有代码。因此,为了更改函数的功能,您必须克隆整个函数链以确保旧版本不会更改。
  • 明白了。我将在下面提供更详细的答案。
  • @ChrisMartinez 谢谢,期待您的回复!

标签: azure asp.net-core api-versioning azure-deployment-slots


【解决方案1】:

@SamaraSoucy-MSFT 是正确的 - 所有选项都有效。 最佳方式是非常主观的,但我将进一步详细说明 API 版本控制的具体选项。

API 版本控制与您的基础架构正交。如果您想将事物拆分为单独的应用程序或添加其他级别的隔离,这是一种受支持的方案。 Version Advertisement 的概念详细描述了这一点。简而言之,您的应用程序可以宣传未在该特定实现中托管的 API 版本。版本广告的实现方式有很多种,因此没有具体的指导。在最简单的模型中,您只需使用新的约定、属性等更新您的应用程序。但是,很可能希望不对现有部署进行任何更改。这意味着您需要想出一种方法来在应用程序之外更新此信息(例如:config、db 等)或放弃版本广告。这部分取决于每个实现的隔离程度。如果您不关心广告可用或已弃用的 API 版本,那么这不是问题。

至少有 4 种方法可以使用 API 版本控制来实现您的目标。

选项 1 - 复制、粘贴、替换

复制、粘贴、替换 (CPR) 方法涉及将服务的先前版本复制并粘贴到新文件夹和新代码命名空间中。这在不更改原始版本的情况下形成了先前版本的新版本的基线。然后根据需要替换新版本中的差异。此过程可以根据需要重复。

如果您的版本之间的更改相当小,这可能是一个非常简单且有效的策略。一个关键的缺点是随着时间的推移膨胀和实现耦合。如果您有可靠的版本控制策略(例如 N-2),那么可以最大限度地减少影响。最大的挑战是进行重大的实施更改,这对共同主持没有意义或可能导致更改以前的版本。这样的示例将尝试在同一实现中使用 ASP.NET Web API 托管 1.0 和 ASP.NET Core 中的 2.0

我已经看到这种方法使用了几次,并且很有效。

选项 2 - 注入和编写

在此变体中,您将在单独的 API 程序集中实现每个版本。您将拥有一个 API 主机应用程序,它注入组合来自每个版本化程序集的所有 API。这提供了实现之间的完全隔离,仍然具有 API 版本控制的所有优点。

选项1一样,你还是要考虑臃肿;特别是因为每个程序集可能具有不同的依赖项。托管为不同平台编写的 API 也非常困难,但在技术上应该是可行的。

选项 3 - 主机标头映射

大多数 Web 服务器都有某种方式将 Host 标头映射到不同的应用程序。您可以使用此技术将应用程序的每个版本托管为独立的应用程序。

选项 4 - 网关

使用网关提供了最大的灵活性,但设置起来可能最具挑战性。此方法可以使用任意数量的路由方法,例如 DNS、URL 重写或基于请求中可用版本信息的 URL 重定向。然后,端点很可能是一个孤立的应用程序,例如 选项 3。网关负责将请求转发或重定向到正确的版本端点。

我使用术语 网关 松散。这可能是现有的服务或平台、基于硬件的或您自己的定制设计。这取决于您的需求以及开箱即用的解决方案是否可以满足这些需求。

其他注意事项

这些当然不是唯一的选择,也不是相互排斥的。您可以组合它们的任何变体以满足您的需求。

选择选项 3选项 4 会给 API 版本控制带来一些挑战,因为物理隔离屏障超越了每个已部署的应用程序。您要么需要想出一种方法来更新广告版本,要么完全放弃这个概念 - 如上所述。如果您最终根本不宣传版本,那么每个部署的实现应该是一个单独的、独立的代码库,可能根本不需要 API 版本控制,因为它是在抽象层处理的。

您的整体版本控制策略和政策也将发挥作用。如果您在您的服务中使用对称版本,则 URL 设计和 API 版本在整体上是一致的,但会附带添加的部署来满足此要求。如果您选择拥有独立的、不断发展的服务,那么版本发现和广告就会变得更加有趣。例如,您的政策可能规定 已弃用 版本将在 6 个月后停用。然后,客户端应通过检测 api-deprecated-versions 响应标头来检测此广告。可以通过HEAD 和/或OPTIONS 方法支持版本发现。

【讨论】:

  • 感谢您花时间回答。保持简短:不需要版本广告,没有版本控制策略(所以没有选项 1)。选项 3+4:就我而言,API 网关已经存在。选项2对我来说并不完全清楚。注入和编写是什么意思?这是否意味着每个版本都被隔离到一个 DLL(程序集)中,然后在运行时加载?
  • 正确。这很可能通过依赖注入 (DI) 来实现。只要它们都被 IActionDescriptorCollectionProvider 服务加载和发现,那么 API 版本控制将继续工作而无需任何其他更改。
【解决方案2】:

最好的方法是适合您用例的方法 - 您提出的所有方法都是有效的。

如果您希望能够在不更改任何代码来进行版本控制的情况下进行单独的设置,那么您可以选择部署槽和容器。在这两者之间,如果您不熟悉 Docker,插槽会更容易使用。

正如您所提到的,虚拟应用程序做类似的事情,但您不能分离配置。

请记住,这意味着在同一个应用服务上运行您的应用的多个副本,因此您需要适当地扩展它。这可能是使用 API 版本控制的最大优势,即使它确实意味着一些不同的编码实践。您仍然只运行一个副本。随着您获得的版本越来越多,运行多个应用副本的成本将会上升,除非您开始弃用旧版本。

所有 Azure 网站都使用 https://{app_name}.azurewebsites.net 网址,因此从技术上讲,它们都具有相同的基础。如果您正在寻找它们都具有相同的子域,那么 API 版本控制或虚拟应用程序是可行的方法,除非您想构建一些重定向逻辑。当然,使用自定义域,您可以更好地控制 DNS 记录的映射方式。

【讨论】:

  • 我要补充一点,部署槽和容器不是相互排斥的。现在可以使用容器注册表作为 Web 应用中部署槽的来源。
猜你喜欢
  • 1970-01-01
  • 2010-09-30
  • 1970-01-01
  • 2021-04-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-09-22
相关资源
最近更新 更多