ASP.NET Core Web API 版本控制

作者 : 慕源网 本文共4721个字,预计阅读时间需要12分钟 发布时间: 2021-12-3 共552人阅读
在本教程中,我们将学习如何开发简单的 Asp Net Core 3.1 Web API 和 API 版本控制技术,例如基于 URL、基于header和基于查询字符串的版本控制。

什么是 Web API 版本控制?为什么我们需要它?

假设我们在生产箱中有一个可用的 API,并且一些客户已经在使用它。后期生产部署,我们应该非常小心任何新的变化。这些更改不应影响已经使用我们 API 的现有客户应用程序。建议客户在集成了我们 API 的每个应用程序中更改 API 调用并不是一个好的做法。为了解决这些问题,API 版本控制出现了。

API 版本确保我们现有客户端应用程序数据的完整性和可用性。

对于实施,我将使用,

  • 微软 Visual Studio 企业版 2019
  • Version 16.8.4
  • ASP.NET Core 3.1
  • 用于Postman 测试 API
P.S

可以使用Visual Studio 2019 社区版。

首先,

第1步

创建一个简单的 ASP.NET Core 3.1 API 项目。

第2步

添加模型 ProductResponse.cs
namespace AspNetCoreVersioning.Contracts {  
    public class ProductResponse {  
        public Guid Id {  
            get;  
            set;  
        }  
        public string Name {  
            get;  
            set;  
        }  
    }  
}  

第 3 步

添加控制器 ProductsController.cs

namespace AspNetCoreVersioning.Controllers {  
    [ApiController]  
    [Route("api/products")]  
    public class ProductsController: ControllerBase {  
        [HttpGet("{productId}")]  
        public IActionResult GetProduct([FromRoute] Guid productId) {  
            var product = new ProductResponse {  
                Id = productId,  
                    Name = "Sanitizer"  
            };  
            return Ok(product);  
        }  
    }  
}  

让我们来测试这个 API,根据您的环境,端口号会有所不同。

https://localhost:12345/api/products/00000000-0000-0000-0000-000000000000

结果

{"id":"00000000-0000-0000-0000-000000000000","name":"Sanitizer"}   

我们已经收到了预期的结果。

假设我们需要对 API 进行重大更改,但我们不想破坏客户已经在使用的现有 API 中的任何内容。我们怎样才能做到这一点?让我们去解析一个 NuGet 包Microsoft.AspNetCore.Mvc.Versioning

从包管理器控制台使用以下命令,

Install-Package Microsoft.AspNetCore.Mvc.Versioning

软件包安装完成后,让我们配置 API 以支持版本控制。这个包基本上有我们需要的一切。

事不宜迟,让我们转到类 Startup.cs,我们将在其中更新 ConfigurationServices 方法,如下所示

public void ConfigureServices(IServiceCollection services) {  
    services.AddControllers();  
    services.AddApiVersioning();  
}  

通过添加这些 services.AddApiVersioning() 方法,我们有某种版本控制。但是,我们还没有真正告诉 ASP.NETCore 我们如何对 API 进行版本控制。不做任何额外更改,让我们运行 API,我们将收到以下错误消息

{"error":{"code":"ApiVersionUnspecified","message":"An API version is required, but was not specified.","innerError":null}}   

这是因为我们尚未将 API 版本控制配置为默认版本。对于我们来说,第一个版本显然是 V1 或 V1.0。这在 ASP.NET Core 中的默认工作方式是使用“API-version”查询字符串参数,如下所示。

https://localhost:12345/api/products/00000000-0000-0000-0000-000000000000?api-version=1

结果如下,

{"id":"00000000-0000-0000-0000-000000000000","name":"Sanitizer"}   

然而,这并不理想,因为如果我们强制要求这个“api-version”查询字符串,我们的许多消费者的代码就会中断。我们想要做的是我们希望启用 API 版本控制默认为一个版本。我们如何才能做到这一点?让我们再次进入 Startup.cs 类并进行以下更改。

public void ConfigureServices(IServiceCollection services) {  
    services.AddControllers();  
    services.AddApiVersioning(options => {  
        options.AssumeDefaultVersionWhenUnspecified = true;  
    });  
}  

让我们再次执行 API,

https://localhost:12345/api/products/00000000-0000-0000-0000-000000000000

Result: {"id":"00000000-0000-0000-0000-000000000000","name":"Sanitizer"}   

假设,如果我们想要一个不同的版本而不是 V1.0 或 V1。我们怎样才能做到这一点?

首先,我们将在 Startup.cs 类中进行以下更改,如下所示,

public void ConfigureServices(IServiceCollection services) {  
    services.AddControllers();  
    services.AddApiVersioning(options => {  
        options.AssumeDefaultVersionWhenUnspecified = true;  
        options.DefaultApiVersion = ApiVersion.Default;  
    });  
}  

然后进行以下两个更改。

第1步

在 ProductResponse.cs 类中添加以下模型,

namespace AspNetCoreVersioning.Contracts {  
    public class ProductResponseV1 {  
        public Guid Id {  
            get;  
            set;  
        }  
        public string Name {  
            get;  
            set;  
        }  
    }  
    public class ProductResponseV2 {  
        public Guid Id {  
            get;  
            set;  
        }  
        public string ProductName {  
            get;  
            set;  
        }  
    }  
}  

第2步

对 ProductsController.cs 类进行以下更改

namespace AspNetCoreVersioning.Controllers {  
        [ApiController]  
        [Route("api/products")]  
        public class ProductsController: ControllerBase {  
            [HttpGet("{productId}")]  
            public IActionResult GetProductV1([FromRoute] Guid productId) {  
                    var product = new ProductResponseV1 {  
                        Id = productId,  
                            Name = "Sanitizer"  
                    };  
                    return Ok(product);  
                }  
                [HttpGet("{productId}")]  
            public IActionResult GetProductV2([FromRoute] Guid productId) {  
                var product = new ProductResponseV2 {  
                    Id = productId,  
                        ProductName = "Sanitizer"  
                };  
                return Ok(product);  
            }  
        }  

现在运行 API。您将收到以下异常。

处理请求时发生未处理的异常。

AmbiguousMatchException: The request matched multiple endpoints. Matches,

AspNetCoreVersioning.Controllers.ProductsController.GetProductV2 (AspNetCoreVersioning)  
AspNetCoreVersioning.Controllers.ProductsController.GetProductV1 (AspNetCoreVersioning)  
Microsoft.AspNetCore.Routing.Matching.DefaultEndpointSelector.ReportAmbiguity(CandidateState[] candidateState) 
为了解决此错误消息,我们需要在 ProductsController.cs 类中进行一些配置更改,如下所示,
namespace AspNetCoreVersioning.Controllers {  
    [ApiController]  
    [Route("api/products")]  
    [ApiVersion("1.0")]  
    [ApiVersion("2.0")]  
    public class ProductsController: ControllerBase {  
        [HttpGet("{productId}")]  
        public IActionResult GetProductV1([FromRoute] Guid productId) {  
                var product = new ProductResponseV1 {  
                    Id = productId,  
                        Name = "Sanitizer"  
                };  
                return Ok(product);  
            }  
            [HttpGet("{productId}")]  
            [MapToApiVersion("2.0")]  
        public IActionResult GetProductV2([FromRoute] Guid productId) {  
            var product = new ProductResponseV2 {  
                Id = productId,  
                    ProductName = "Sanitizer"  
            };  
            return Ok(product);  
        }  
    }  
}  

现在运行 API,如下所示,

https://localhost:12345/api/products/00000000-0000-0000-0000-000000000000?api-version=1

Result: {"id":"00000000-0000-0000-0000-000000000000","name":"Sanitizer"}  

https://localhost:12345/api/products/00000000-0000-0000-0000-000000000000?api-version=2

Result: {"id":"00000000-0000-0000-0000-000000000000","productName":"Sanitizer"}   

我将在接下来的会议中介绍基于 URL 和基于Head的版本控制。感谢您阅读我的文章。我感谢您在下面的评论部分中的反馈。


慕源网 » ASP.NET Core Web API 版本控制

常见问题FAQ

程序仅供学习研究,请勿用于非法用途,不得违反国家法律,否则后果自负,一切法律责任与本站无关。
请仔细阅读以上条款再购买,拍下即代表同意条款并遵守约定,谢谢大家支持理解!

发表评论

开通VIP 享更多特权,建议使用QQ登录