java 单机接口限流处理方案
343
2022-06-07
在后端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);
});
分别在两个不同的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版本
一般在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版本号。
我们还可以使用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测试
修改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的名字。
当哪个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
功能还能强大的,基本满足了大部分的需求,还有一些功能可能没有在本文中涉及到,可以去这里.翻阅。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~