前言

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

开始

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

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

Install-Package Microsoft.AspNetCore.Mvc.Versioning

最新版本已经支持Core3.1

项目结构如下

StartupConfigureServices 中增加一下配置。

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功能还能强大的,基本满足了大部分的需求,还有一些功能可能没有在本文中涉及到,可以去这里.翻阅。

Asp.Net.Core WebApi 版本控制的更多相关文章

  1. ASP.NET Core WebApi版本控制

    前言: 在日常项目开发中,随着项目需求不断的累加.不断的迭代:项目服务接口需要向下兼容历史版本:前些时候就因为Api接口为做版本管理导致接口对低版本兼容处理不友好. 最近就像了解下如何实现WebApi ...

  2. ASP.Net Core WebApi几种版本控制对比

    版本控制的好处: (1)助于及时推出功能, 而不会破坏现有系统. (2)它还可以帮助为选定的客户提供额外的功能. API 版本控制可以采用不同的方式进行控制,方法如下: (1)在 URL 中追加版本或 ...

  3. 零基础ASP.NET Core WebAPI团队协作开发

    零基础ASP.NET Core WebAPI团队协作开发 相信大家对“前后端分离”和“微服务”这两个词应该是耳熟能详了.网上也有很多介绍这方面的文章,写的都很好.我这里提这个是因为接下来我要分享的内容 ...

  4. ASP.NET Core WebApi构建API接口服务实战演练

    一.ASP.NET Core WebApi课程介绍 人生苦短,我用.NET Core!提到Api接口,一般会想到以前用到的WebService和WCF服务,这三个技术都是用来创建服务接口,只不过Web ...

  5. asp.net core webapi之跨域(Cors)访问

    这里说的跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被当作 ...

  6. ASP.NET Core WebAPI 开发-新建WebAPI项目

    ASP.NET Core WebAPI 开发-新建WebAPI项目, ASP.NET Core 1.0 RC2 即将发布,我们现在来学习一下 ASP.NET Core WebAPI开发. 网上已经有泄 ...

  7. Asp.net Core WebApi 使用Swagger做帮助文档,并且自定义Swagger的UI

    WebApi写好之后,在线帮助文档以及能够在线调试的工具是专业化的表现,而Swagger毫无疑问是做Docs的最佳工具,自动生成每个Controller的接口说明,自动将参数解析成json,并且能够在 ...

  8. Asp.Net Core WebApi学习笔记(四)-- Middleware

    Asp.Net Core WebApi学习笔记(四)-- Middleware 本文记录了Asp.Net管道模型和Asp.Net Core的Middleware模型的对比,并在上一篇的基础上增加Mid ...

  9. Asp.net core WebApi 使用Swagger生成帮助页

    最近我们团队一直进行.net core的转型,web开发向着前后端分离的技术架构演进,我们后台主要是采用了asp.net core webapi来进行开发,开始每次调试以及与前端人员的沟通上都存在这效 ...

随机推荐

  1. 多道技术 进程 线程 协程 GIL锁 同步异步 高并发的解决方案 生产者消费者模型

    本文基本内容 多道技术 进程 线程 协程 并发 多线程 多进程 线程池 进程池 GIL锁 互斥锁 网络IO 同步 异步等 实现高并发的几种方式 协程:单线程实现并发 一 多道技术 产生背景 所有程序串 ...

  2. Ajax同步和异步的区别?

    今天在code review时候看到同事的代码,用了ajax同步,async:false,如果不设置async参数,默认是true,为异步,异步的情况是比较复杂的,看下同步这个例子: function ...

  3. 一起了解 .Net Foundation 项目 No.17

    .Net 基金会中包含有很多优秀的项目,今天就和笔者一起了解一下其中的一些优秀作品吧. 中文介绍 中文介绍内容翻译自英文介绍,主要采用意译.如与原文存在出入,请以原文为准. Peachpie Comp ...

  4. Python进阶练习与爬取豆瓣T250的影片相关信息

    (一)Python进阶练习 正所谓要将知识进行实践,才会真正的掌握 于是就练习了几道题:求素数,求奇数,求九九乘法表,字符串练习 import re #求素数 i=1; flag=0 while(i& ...

  5. Java集合01——List 的几个实现类,了解一下?

    从本文起,我们将开始分享 Java 集合方面的知识,关注公众号「Java面典」了解更多 Java 知识点. List 是继承于 Collection 的接口,其实现类有 ArrayList,Linke ...

  6. 基于RabbitMQ和Swoole实现的一个完整的异步任务系统

    从最开始的使用redis实现的单进程消费的异步任务系统到加入swoole的多进程消费模式,现在,我们的异步任务系统终于又能迈进一步. 因为有了前面两个简单系统的经验,这回基于RabbitMQ的异步任务 ...

  7. 【BIM】BIMFACE中创建矢量文本[下篇]

    背景 在上一篇文章中,我们通过THREEJS创建了矢量文本,并添加到了BIMFACE场景中,但是仅仅加入到场景中并不是我们的目的,我们的目的是把这种矢量文本加到指定的构件或者空间上,以此标识该构件或空 ...

  8. POJ 1879

    栈和队列的综合应用,利用栈和队列分别模拟分,5分,时槽,以及小球队列 利用求出一天后的置换可以求出周期,进而求出最大公约数(可以利用矩阵的角度,也许可以简化,因为每次都是乘上一个相同的置换矩阵) 要注 ...

  9. PBM error occurred during PreCloneCheckCallback: 由于目标计算机积极拒绝,无法连接

    问题如下: 迁移存储和主机的时候发生错误,错误如下: 出现了常规系统错误: PBM error occurred during PreCloneCheckCallback: 由于目标计算机积极拒绝,无 ...

  10. git基础教程(八)

    8. gitlab相关介绍 8.1 gitlab优势 社区版本,自己可以在公司搭建环境 维护人员多,版本更新块 易用性强,上手快 集成CI(持续集成) 集成CD(持续发布) 8.2 持续集成 8.2. ...