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…

用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 通常是现场授课,但本次由于疫情的限制导致人们不得不尽可能减少外出…

数据结构与算法--力扣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#项目中使用…

SpringBoot自动装配源码解析

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

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

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

玉柴spn码故障对照表_后处理的故障不总是尿素泵故障,也有可能是这些原因

之前说到后处理故障,解决的都是柴油机尿素泵、喷嘴的,而SCR箱同样是一个重要的部件,它的作用就是将尿素液与尾气中的氮氧化物充分混合并发生化学反应的场所,目前重卡SCR箱集SCR催化器和发动机排气消声器与一体。整体材料为不锈钢&…

SpringBoot中Bean按条件装配

Conditional条件装配 Conditional是Spring Framework提供的一个核心功能注解,这个注解的作用是提供自动装配的条件限制,一般我们在用Configuration,Bean的时候使用它。也就是我们在自定义Bean的注入的时候,我们可以通过Condition…

定义一个手表_华米Amazfit Pop评测:一款功能全面的“性价比”手表

目前的智能手表虽然品牌、型号众多,但基本可以分为二种类型:第一种为入门级智能手表,其功能单一与智能手环差不多,但胜在屏幕大、能够带来更好的观感且价格便宜;第二种为旗舰级智能手表,功能全面、硬件水准…

[Java基础]复制文件的异常处理try...catch...finally的做法

代码如下: package ErrorOperatorPack;import java.io.FileReader; import java.io.FileWriter; import java.io.IOException;public class CopyFileDemo01 {public static void main(String[] args){}private static void method() {FileReader fr null;FileWriter fw null…