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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/310280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[Java基础]字节缓冲流

字节缓冲输出流: package InstreamPack;import java.io.BufferedOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets;public class BufferStreamDemo01 {public s…

matlab 判断鼠标按下,Matlab:如何通过使用回调来获取当前鼠标在点击位置

I googled near and far, but couldnt get an example of how you associate a callback to the click event in matlab. Can someone show me an example?解决方案Define the WindowButtonDownFcn of your figure callback using the set command and an callbackfunction ta…

Python 推导,内含,迭代器

Python语法–推导或内含 list comprehension操作可以将一个序列类型的数据集推导出另一个序列类型的数据集: 典型的情况: for i in aiterator利用推导获取一个平方数列表 square [i * i for i in range(1, 11)]以上情况同如下循环 for i in range(…

用asp.net core结合fastdfs打造分布式文件存储系统

最近被安排开发文件存储微服务,要求是能够通过配置来无缝切换我们公司内部研发的文件存储系统,FastDFS,MongDb GridFS,阿里云OSS,腾讯云OSS等。根据任务紧急度暂时先完成了通过配置来无缝切换内部文件系统以及FastDFS。…

仅仅有人物没背景的图片怎么弄_五分钟写作课 人物篇 人物的出场是个关键时刻...

我看过不少故事,人物出场了,说了几句话,然后离开,读者知道他是某人的爸爸,学校的老师,某个企业的老板,除了这些定为之外,他自己是怎样的性格?怎样的形象呢?没…

数据结构与算法一篇帮助你吃下KMP算法

模式匹配 什么是模式匹配,我们用一个案例来说明: 当S “s1,s2,s3,s4 …sn” T“t1,t2,t3,t4 … tn” 在字符串S中寻找T字符串的过程就是模式匹配的过程,T就说模式串,S是主串 实现方案: 暴力破解,逐字符判…

在远程 CSM 课程中体验线上工作坊

4.11 日周六,我参与了由 Bob 老师组织讲授的一期 Certified Scrum Master(即 CSM)课程,从中收获颇丰,特记于此,与君分享。CSM 通常是现场授课,但本次由于疫情的限制导致人们不得不尽可能减少外出…

python中的max_row_Openpyxl max_row和max_column错误地报告了一个较大的figu

我的查询是处理作为Im开发的解析脚本的一部分的函数。我试图编写一个python函数来查找与excel中匹配值对应的列号。excel是用openpyxl动态创建的,它有第一行(来自第三列)标题,每个标题跨4列合并为一行。在我的后续函数中,我正在分析一些要添加…

数据结构与算法--力扣108题将有序数组转换为二叉搜索树

力扣108提将有序数组转换为二叉搜索树 近一年都比较关注算法相关的知识,也刷了不少题,之前的文章中大多也是算法相关的文章,但是感觉每次遇到树相关的题型都不能应对自如,因此还是有必要在相关知识上下功夫,因此有此次…

C#验证IP是否为局域网地址的三种方法

C#验证IP是否为局域网地址的三种方法前一阵子有【广州.NET群】的客户问起这个问题,说他们需要验证客户输入的网站是否为局域网。其实局域网的 IP并没有确定的定义,只要是局域网中,即可设置为任何一个 IP。但确实存在一个 内网保留地址的定义&…

扫地机器人隔板_【扫地机器人使用】_摘要频道_什么值得买

至于扫地机的单边刷好还是双边刷好,这个也是我原本有的问题,后来经过好友解答才知道,单边刷其实并不比双边刷效率低。对于带拖地功能的扫地机而言,更好的应该是单边刷。因为边刷主要的功能是将一些边缘角落的垃圾扫出来让主刷清洁…

数据结构与算法--力扣109题将有序双向链表转换为二叉搜索树

将有序数组转换为二叉搜索树 近一年都比较关注算法相关的知识,也刷了不少题,之前的文章中大多也是算法相关的文章,但是感觉每次遇到树相关的题型都不能应对自如,因此还是有必要在相关知识上下功夫,因此有此次总结&…

[Java基础]字符缓冲流

代码如下: package CopyJavaPack01;import java.io.BufferedWriter; import java.io.FileWriter; import java.io.IOException;public class CopyJavaDemo04 {public static void main(String[] args) throws IOException {BufferedWriter bw new BufferedWriter(new FileWri…

在C#中使用RESTful API的几种好方法

在C#中使用RESTful API的几种好方法原文来自互联网,由长沙DotNET技术社区编译。 通过Web开发的路径,您发现自己迟早需要处理外部API(应用程序编程接口)。在本文中,我的目标是列出在C#项目中使用…

spine 导出纹理_Spine 纹理打包Texture packing_官方文档中文版

马上注册,加入CGJOY,让你轻松玩转CGJOY。您需要 登录 才可以下载或查看,没有帐号?立即注册x本帖最后由 笑虾 于 2014-10-7 20:45 编辑欢迎入群 Spine2D骨骼动画 1群:7708065,2群:225097509大家…

SpringBoot自动装配源码解析

Spring Boot 自动装配原理 使用Spring Boot最方便的一点体验在于我们可以几零配置的搭建一个Spring Web项目,那么他是怎么做到不通过配置来对Bean完成注入的呢。这就要归功于Spring Boot的自动装配实现,他也是Spring Boot中各个Starter的实现基础&#…

自制 .NET Core 路由调试中间件

点击上方蓝字关注“汪宇杰博客”导语本文教大家如何在 .NET Core 应用中使用中间件输出路由信息以便调试程序。背景在 .NET Framework 的上古时代,有个叫做 RouteDebugger 的神器,可以在 MVC 或 Web API 应用中输出当前页面的路由信息,也可查…