Asp.Net.Core WebApi 版本控制

简介:

Asp.Net.Core WebApi 版本控制

前言
在后端Api的开发过程中,无法避免的会遇到接口迭代的过程,如何保证新老接口的共存和接口的向前的兼容呢,这时候就需要对Api进行版本的控制,那如何优雅的控制Api的版本呢?

开始
Microsoft.AspNetCore.Mvc.Versioning 是一个微软官方推出的一个用于管理Api版本的包,配置简单,功能强大。 github地址.

新建一个WebApi项目并通过命令引用包。

Install-Package Microsoft.AspNetCore.Mvc.Versioning

最新版本已经支持Core3.1

项目结构如下

在 Startup 的 ConfigureServices 中增加一下配置。

services.AddApiVersioning(options =>
{

options.ReportApiVersions = true; 
options.AssumeDefaultVersionWhenUnspecified = true; 
options.DefaultApiVersion = new ApiVersion(1, 0); 

});
ReportApiVersions:是否在请求头中返回受支持的版本信息。
AssumeDefaultVersionWhenUnspecified:请求没有指明版本的情况下是否使用默认的版本。
DefaultApiVersion:默认的版本号。
通过QueryString进行版本控制
分别在两个不同的Controller中添加一个获取版本信息的接口

namespace version.Controllers.v1
{

[ApiVersion("1.0")]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
namespace version.Controllers.v2
{

[ApiVersion("2.0")]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
HttpContext.GetRequestedApiVersion().ToString() 是用于获取请求接口的版本信息。

我们通过postman来请求这两个接口当我们没有给到具体请求哪个版本的时候会根据在ConfigureServices中配置的默认版本去执行。

指定版本请求结果

在响应头中会显示当前支持的所有的Api版本

通过URL Path进行版本控制
一般在Api开发中不会去QueryString的方式去进行版本控制,而是使用URL路径段的方式来控制版本。

修改两个Controller中的代码如下。

namespace version.Controllers.v1
{

[ApiVersion("1.0")]
[ApiController]
[Route("api/v{version:ApiVersion}/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
namespace version.Controllers.v2
{

[ApiVersion("2.0")]
[ApiController]
[Route("api/v{version:ApiVersion}/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
通过postman进行测试

可以看到当我们使用指定的版本是可以正常访问的时候,但是如果我们去掉了Api版本号就会抛出404,并不能像QueryString一样调用默认的Api版本,因为URL Path的方式不允许隐式匹配设置的默认Api版本。所以必须申明所有的Api版本。且在请求Api同时必须带上Api版本号。

通过Media Type进行版本控制
我们还可以使用content-type来实现版本的控制

修改ConfigureServices中的配置

services.AddApiVersioning(options =>
{

options.ApiVersionReader = new MediaTypeApiVersionReader();
options.AssumeDefaultVersionWhenUnspecified = true;
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);

});
CurrentImplementationApiVersionSelector 如果没有在content-type中传递Api版本好,将默认匹配最新的Api版本

分别修改两个Controller

namespace version.Controllers.v1
{

[ApiVersion("1.0")]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
namespace version.Controllers.v2
{

[ApiVersion("2.0")]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
使用Postman测试

通过自定义Headers进行版本控制
修改ConfigureServices中的配置

services.AddControllers();
services.AddApiVersioning(options =>
{

options.ReportApiVersions = true;
options.ApiVersionReader = new HeaderApiVersionReader("api_version");
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);

});
api_version 是你Headers中Key的名字。

使用Postman测试

特性
当哪个Api版本不在更新,就需要弃用掉这个版本。当Deprecated值为true时说明该Api版本已经已经弃用,但是弃用不代表不能请求。只是会在响应头中告知次版本已经已经弃用。

namespace version.Controllers.v1
{

[ApiVersion("1.0",Deprecated= true)]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}

项目总有一些功能是不需要版本的控制,所以我们希望它不受版本控制。可以添加[ApiVersionNeutral]特性使Api支持版本控制。

namespace version.Controllers.v1
{

[ApiVersionNeutral]
[ApiController]
[Route("api/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
MapToApiVersion 可以将单个Api归类于任何版本。在一个Controller中可以存在多个版本的Api。我们可以配合Deprecated来灵活的控制我们的Api。

namespace version.Controllers.v1
{

[ApiVersion("3.0")]
[ApiVersion("1.0",Deprecated= true)]
[ApiController]
[Route("api/v{version:ApiVersion}/[controller]")]
public class ValuesController : Controller
{
    [HttpGet("version"), MapToApiVersion("1.0")]
    public string Version() => (HttpContext.GetRequestedApiVersion().ToString());

    [HttpGet("version3"), MapToApiVersion("3.0")]
    public string Version3() => (HttpContext.GetRequestedApiVersion().ToString());
}

}
通过postman测试一下。

总结
可以看到Microsoft.AspNetCore.Mvc.Versioning功能还能强大的,基本满足了大部分的需求,还有一些功能可能没有在本文中涉及到,可以去这里.翻阅。

原文地址https://www.cnblogs.com/linhuiy/p/12668535.html

相关文章
|
2月前
|
开发框架 监控 前端开发
在 ASP.NET Core Web API 中使用操作筛选器统一处理通用操作
【9月更文挑战第27天】操作筛选器是ASP.NET Core MVC和Web API中的一种过滤器,可在操作方法执行前后运行代码,适用于日志记录、性能监控和验证等场景。通过实现`IActionFilter`接口的`OnActionExecuting`和`OnActionExecuted`方法,可以统一处理日志、验证及异常。创建并注册自定义筛选器类,能提升代码的可维护性和复用性。
|
3月前
|
XML 开发框架 .NET
ASP.NET Web Api 如何使用 Swagger 管理 API
ASP.NET Web Api 如何使用 Swagger 管理 API
|
3月前
|
开发框架 前端开发 .NET
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
ASP.NET MVC WebApi 接口返回 JOSN 日期格式化 date format
42 0
|
3月前
|
存储 开发框架 .NET
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
ASP.NET Web Api 使用 EF 6,DateTime 字段如何取数据库服务器当前时间
|
3月前
|
开发框架 .NET API
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
如何在 ASP.NET Core Web Api 项目中应用 NLog 写日志?
141 0
|
3月前
|
开发框架 .NET API
分享一个 ASP.NET Web Api 上传和读取 Excel的方案
分享一个 ASP.NET Web Api 上传和读取 Excel的方案
102 0
|
3月前
|
开发框架 中间件 .NET
分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法
分享 ASP.NET Core Web Api 中间件获取 Request Body 两个方法
107 0
|
2月前
|
开发框架 前端开发 JavaScript
ASP.NET MVC 教程
ASP.NET 是一个使用 HTML、CSS、JavaScript 和服务器脚本创建网页和网站的开发框架。
35 7
|
2月前
|
存储 开发框架 前端开发
ASP.NET MVC 迅速集成 SignalR
ASP.NET MVC 迅速集成 SignalR
48 0
|
3月前
|
开发框架 前端开发 安全
ASP.NET MVC 如何使用 Form Authentication?
ASP.NET MVC 如何使用 Form Authentication?