使用.NET 6开发TodoList应用(21)——实现API版本控制
系列导航及源代码
需求
API接口版本管理,对于一些规模稍大的企业应用来说,是经常需要关注的一大需求。尽管我们的示例程序TodoList很简单,但是我们也可以通过这个应用程序,来实践一下如何管理API接口版本。
目标
实现API接口版本管理。
原理与思路
要实现API版本管理,我们需要这个库:Microsoft.AspNetCore.Mvc.Versioning
。它提供了.NET Web项目接口的版本管理功能。
实现
添加Nuget Package并配置服务
向Api
项目中添加Microsoft.AspNetCore.Mvc.Versioning
包。并添加一个扩展方法:
ApiServiceExtensions.cs
using Microsoft.AspNetCore.Mvc;
namespace TodoList.Api.Extensions;
public static class ApiServiceExtensions
{
public static void ConfigureApiVersioning(this IServiceCollection services)
{
services.AddApiVersioning(options =>
{
// 向响应头中添加API版本信息
options.ReportApiVersions = true;
// 如果客户端不显式指定API版本,则使用默认版本
options.AssumeDefaultVersionWhenUnspecified = true;
// 配置默认版本为1.0
options.DefaultApiVersion = new ApiVersion(1, 0);
});
}
}
在Program
中调用:
Program.cs
// 省略其他...
builder.ConfigureLog();
builder.Services.ConfigureApiVersioning();
实现API版本控制
方法1: 添加ApiVersion
属性
我们复制一份TodoItemController
到新文件TodoItemV2Controller
并修改类名和构造函数,其他保持原样。为了给Controller标记对应的API版本号,我们分别向两个Controller上添加属性:
[ApiVersion("2.0")]
[Route("/todo-item")]
[ApiController]
public class TodoItemV2Controller : ControllerBase
{
private readonly IMediator _mediator;
// 省略其他...
}
以及
[ApiVersion("1.0")]
[Route("/todo-item")]
[ApiController]
public class TodoItemController : ControllerBase
{
private readonly IMediator _mediator;
// 省略其他..
}
验证1: 请求中不添加任何API版本相关字段
启动Api
项目,执行查询TodoItem
的请求:
- 请求
-** 响应**
日志输出:
结果返回:
以及响应头信息中包含的api-supported-versions
:
验证2: 请求中添加查询字符串api-version
启动Api
项目,执行查询TodoItem
的请求:
请求
响应
日志输出:
结果返回(可以自己尝试修改内部逻辑,这里我懒了没改实现,不过从日志已经能看出请求确实进入了V2版本的Controller):
以及响应头信息中包含的api-supported-versions
:
方法2: 通过请求头携带API版本信息
为了实现这一点,需要在ConfigureApiVersioning
中增加配置:
ApiServiceExtensions.cs
// 省略其他...
// 指定请求头中携带用于指定API版本信息的字段
options.ApiVersionReader = new HeaderApiVersionReader("api-version");
验证3: 通过请求头携带API版本信息
启动Api
项目,执行查询TodoItem
的请求:
请求
响应
日志输出:
返回结果就不继续贴了,以及响应头信息中包含的api-supported-versions
:
方法3: 通过URL路径访问对应的版本
除了这种之外的以上几种方法,都不需要修改接口的URI,而这种方式需要修改URI路径。我们在两个Controller上修改URI如下:
[ApiVersion("2.0")]
[Route("/{v:apiVersion}/todo-item")]
[ApiController]
// 省略其他...
验证4: 通过URI路径选择API版本
启动Api
项目,执行查询TodoItem
的请求:
请求
响应
日志输出:
返回结果就不继续贴了,以及响应头信息中包含的api-supported-versions
:
一点扩展
有的时候我们需要标记一个版本的请求为deprecated
,但是还不想完全删除这个Controller,可以用下面的方式进行标记,这样返回头中会指出这个版本的API已经处于deprecated
状态了。
[ApiVersion("2.0", Deprecated = true)]
[Route("/{v:apiVersion}/todo-item")]
[ApiController]
// 省略其他...
或者在ConfigureApiVersioning
中使用Convention进行标记:
// 省略其他...
// 使用Convention标记deprecated
options.Conventions.Controller<TodoItemV2Controller>().HasDeprecatedApiVersion(new ApiVersion(2, 0));
我们再请求2.0版本的API时,仍然可以获取数据,但是得到的返回头中信息如下:
对比使用Convention方式标记的返回头:
总结
在本文中我们使用多种方式实现了管理API版本的需求,可以根据具体的需要选择一种进行实现。下一篇我们介绍关于响应的缓存实现。
使用.NET 6开发TodoList应用(21)——实现API版本控制的更多相关文章
- 使用.NET 6开发TodoList应用(27)——实现API的Swagger文档化
系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在日常开发中,我们需要给前端提供文档化的API接口定义,甚至需要模拟架设一个fake服务用来调试接口字段.或者对于后端开发人员 ...
- 使用.NET 6开发TodoList应用(3)——引入第三方日志库
需求 在我们项目开发的过程中,使用.NET 6自带的日志系统有时是不能满足实际需求的,比如有的时候我们需要将日志输出到第三方平台上,最典型的应用就是在各种云平台上,为了集中管理日志和查询日志,通常会选 ...
- 使用.NET 6开发TodoList应用(1)——系列背景
前言 想到要写这样一个系列博客,初衷有两个:一是希望通过一个实践项目,将.NET 6 WebAPI开发的基础知识串联起来,帮助那些想要入门.NET 6服务端开发的朋友们快速上手,对使用.NET 6开发 ...
- 使用.NET 6开发TodoList应用(2)——项目结构搭建
为了不影响阅读的体验,我把系列导航放到文章最后了,有需要的小伙伴可以直接通过导航跳转到对应的文章 : P TodoList需求简介 首先明确一下我们即将开发的这个TodoList应用都需要完成什么功能 ...
- 使用.NET 6开发TodoList应用(4)——引入数据存储
需求 作为后端CRUD程序员(bushi,数据存储是开发后端服务一个非常重要的组件.对我们的TodoList项目来说,自然也需要配置数据存储.目前的需求很简单: 需要能持久化TodoList对象并对其 ...
- 使用.NET 6开发TodoList应用(5)——领域实体创建
需求 上一篇文章中我们完成了数据存储服务的接入,从这一篇开始将正式进入业务逻辑部分的开发. 首先要定义和解决的问题是,根据TodoList项目的需求,我们应该设计怎样的数据实体,如何去进行操作? 长文 ...
- 使用.NET 6开发TodoList应用(5.1)——实现Repository模式
需求 经常写CRUD程序的小伙伴们可能都经历过定义很多Repository接口,分别做对应的实现,依赖注入并使用的场景.有的时候会发现,很多分散的XXXXRepository的逻辑都是基本一致的,于是 ...
- 使用.NET 6开发TodoList应用(6)——使用MediatR实现POST请求
需求 需求很简单:如何创建新的TodoList和TodoItem并持久化. 初学者按照教程去实现的话,应该分成以下几步:创建Controller并实现POST方法:实用传入的请求参数new一个数据库实 ...
- 使用.NET 6开发TodoList应用文章索引
系列导航 使用.NET 6开发TodoList应用(1)--系列背景 使用.NET 6开发TodoList应用(2)--项目结构搭建 使用.NET 6开发TodoList应用(3)--引入第三方日志 ...
随机推荐
- error信息
/opt/hadoop/src/contrib/eclipse-plugin/build.xml:61: warning: 'includeantruntime' was not set, defau ...
- 【Linux】【Services】【Package】rpm包制作
1. 概念 1.1. BUILD:源代码解压之后存放的位置 1.2. RPMS:制作完成之后的RPM包的存放位置,包括架构的子目录,比如x86,x86_64 1.3. SOURCES:所有的原材料都应 ...
- VectorCAST - 通过确保测试的完整性控制产品质量
软件测试面临的问题有一句格言是这样说的,"如果没有事先做好准备,就意味着做好了 失败的准备."如果把这个隐喻应用在软件测试方面,就可以这样说"没有测试到,就意味着测试失败 ...
- C#和.NET 框架
C#和.NET框架 在.NET之前 20世纪90年代,微软平台多数程序员使用VB.C或C++.他们使用的技术都有问题. 技术 问题 纯Win32 API 不是面向对象,工作量比MFC大 MFC(Mic ...
- TSN 时间敏感网络:缘起 (TSN历史与现状)
前言 随着工业物联网(IIoT)的兴起和工业4.0的提出,越来越多的设计师.工程师和最终用户关注时间敏感网络(Time-Sensitive Networking,下简称为TSN).TSN为以太网提供确 ...
- [WPF] 用 OpacityMask 模仿 UWP 的 Text Shimmer 动画
1. UWP 的 Text Shimmer 动画 在 UWP 的 Windows Composition Samples 中有一个 Text Shimmer 动画,它用于展示如何使用 Composit ...
- 30个类手写Spring核心原理之自定义ORM(上)(6)
本文节选自<Spring 5核心原理> 1 实现思路概述 1.1 从ResultSet说起 说到ResultSet,有Java开发经验的"小伙伴"自然最熟悉不过了,不过 ...
- ciscn_2019_ne_5
首先checksec和查看多少位的程序 可以看到是32位的程序,放入ida中 进入getflag 可以看到strcpy存在栈溢出,所以大体思路就是输入密码进入选择1造成溢出然后进入选择4获取shell ...
- 一道栈溢出babystack
我太天真了,师傅说让我做做这个平台的题,我就注册了个号,信心满满的打开了change,找到了pwn,一看第一道题是babystack,我想着,嗯,十分钟搞定他!直到我下载了题目,题目给了libc,然后 ...
- [BUUCTF]PWN10——[第五空间2019 决赛]PWN5
[第五空间2019 决赛]PWN5 题目网址:https://buuoj.cn/challenges#[第五空间2019%20决赛]PWN5 步骤: 例行检查,32位,开启了nx和canary(栈保护 ...