当前位置:网站首页>. Net webapi to realize interface version control and get through swagger support
. Net webapi to realize interface version control and get through swagger support
2022-07-17 23:50:00 【[illusory private school]】
High quality resource sharing
| Learning route guidance ( Click unlock ) | Knowledge orientation | Crowd positioning |
|---|---|---|
| 🧡 Python Actual wechat ordering applet 🧡 | Progressive class | This course is python flask+ Perfect combination of wechat applet , From the deployment of Tencent to the launch of the project , Create a full stack ordering system . |
| Python Quantitative trading practice | beginner | Take you hand in hand to create an easy to expand 、 More secure 、 More efficient quantitative trading system |
We are developing webapi If you encounter api When the interface needs to support multiple versions at the same time , For example, after the interface is modified, but you want to support the old version of the front end ( The front end here may be a web page , May be app, Applet wait ) To call , This is common in app, After all, we can actively control the release of the front-end web pages , As long as the unified release, everyone's browser will reload the latest version of the code the next time they visit the web page , But like app There is no guarantee that users will update the latest version as soon as possible app, So it often needs api The interface can maintain multiple versions of logic at the same time , It is the same as the caller that supports new and old versions app To call .
Take an example of the above description :
For example, an interface for creating users ,api/user/createuser
If we modify the input and return parameters of the interface at this time , But I hope the original api/user/createuser The interface logic can also work normally , Common practices are as follows :
- Modify the interface name , Define the new create user interface address as api/user/newcreateuser
- url Incoming version mark , Define the new create user interface address as api/user/createuser?api-version=2
- header Incoming version mark , Pass verification header Medium api-version Value of field , Used to distinguish between calling different versions api
The defect of the first method is obvious , When there are many interface versions, the address definition of the interface will be messy , This article mainly explains the latter two methods , How to be in asp.net webapi Elegant use in the project header perhaps query Pass in Version mark , Used to support api Logical coexistence of multiple versions of , And expand Swagger To achieve SwaggerUI about api-version Support for .
As of the writing time of this article , Abreast of the times .net Version is .net6 , All the examples in this article are also based on .net 6 To build .
First create a asp.net webapi project , This article USES the vs2022 Create directly asp.net webapi project
After the project is created, install the following nuget package :
Swashbuckle.AspNetCore
Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
register api Version control services
#region register api version control
builder.Services.AddApiVersioning(options =>
{
// adopt Header Inform the client of the supported version
options.ReportApiVersions = true;
// It is allowed to call the interface directly without version mark
options.AssumeDefaultVersionWhenUnspecified = true;
// Interface default version
//options.DefaultApiVersion = new ApiVersion(1, 0);
// If no version mark is added, the current highest version will be processed by default
options.ApiVersionSelector = new CurrentImplementationApiVersionSelector(options);
// Configured from Header Pass in api-version
options.ApiVersionReader = new HeaderApiVersionReader("api-version");
// Configured from Query Pass in api-version
//options.ApiVersionReader = new QueryStringApiVersionReader("api-version");
});
builder.Services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
#endregion
Here we can choose api-version The version mark is passed in from url query Transfer or from http header Pass on .
Remove the default swagger To configure
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
Use the following swagger To configure
#region register Swagger
builder.Services.AddTransient, SwaggerConfigureOptions>();
builder.Services.AddSwaggerGen(options =>
{
options.OperationFilter();
options.IncludeXmlComments(Path.Combine(AppContext.BaseDirectory, $"{typeof(Program).Assembly.GetName().Name}.xml"), true);
});
#endregion
#region Enable Swagger
// Enable middleware service generation Swagger As JSON Endpoint
app.UseSwagger();
// Enable middleware service pair swagger-ui, Appoint Swagger JSON Endpoint
app.UseSwaggerUI(options =>
{
var apiVersionDescriptionProvider = app.Services.GetRequiredService();
foreach (var description in apiVersionDescriptionProvider.ApiVersionDescriptions)
{
options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}
options.RoutePrefix = "swagger";
});
#endregion
Two custom classes are used SwaggerConfigureOptions and SwaggerOperationFilter ,
SwaggerConfigureOptions Is a custom Swagger Configuration method , Mainly used according to api The description on the controller is used to add different versions of SwaggerDoc;
SwaggerOperationFilter Is a user-defined filter, mainly to achieve SwaggerUI Version parameters for api-version Required validation and marking expired api The function of , The details are as follows
SwaggerConfigureOptions .cs
///
/// To configure swagger Build options .
///
public class SwaggerConfigureOptions : IConfigureOptions
{
readonly IApiVersionDescriptionProvider provider;
public SwaggerConfigureOptions(IApiVersionDescriptionProvider provider) => this.provider = provider;
public void Configure(SwaggerGenOptions options)
{
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName, CreateInfoForApiVersion(description));
var modelPrefix = Assembly.GetEntryAssembly()?.GetName().Name + ".Models.";
var versionPrefix = description.GroupName + ".";
options.SchemaGeneratorOptions = new SchemaGeneratorOptions { SchemaIdSelector = type => (type.ToString()[(type.ToString().IndexOf("Models.") + 7)..]).Replace(modelPrefix, "").Replace(versionPrefix, "").Replace("`1", "").Replace("+", ".") };
}
}
static OpenApiInfo CreateInfoForApiVersion(ApiVersionDescription description)
{
var info = new OpenApiInfo()
{
Title = Assembly.GetEntryAssembly()?.GetName().Name,
Version = "v" + description.ApiVersion.ToString(),
//Description = "",
//Contact = new OpenApiContact() { Name = "", Email = "" }
};
if (description.IsDeprecated)
{
info.Description += " this Api " + info.Version + " Version deprecated , Please upgrade the new version as soon as possible ";
}
return info;
}
}
SwaggerOperationFilter.cs
///
/// swagger Integrate multiple versions api Custom Settings
///
public class SwaggerOperationFilter : IOperationFilter
{
public void Apply(OpenApiOperation operation, OperationFilterContext context)
{
var apiDescription = context.ApiDescription;
// Determine the interface abandonment status , Mark and adjust the interface
operation.Deprecated |= apiDescription.IsDeprecated();
if (operation.Parameters == null)
{
return;
}
// by api-version Add required validation for parameters
foreach (var parameter in operation.Parameters)
{
var description = apiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
if (parameter.Description == null)
{
parameter.Description = description.ModelMetadata?.Description;
}
if (parameter.Schema.Default == null && description.DefaultValue != null)
{
parameter.Schema.Default = new OpenApiString(description.DefaultValue.ToString());
}
parameter.Required |= description.IsRequired;
}
}
}
After all these are configured , Began to The control module adjusts
For the convenience of code version differentiation , So I'm here Controllers Create a separate folder according to the version v1 and v2
And then in v1 and v2 The folder of is protected against Controllers, The structure is shown in the figure below

Then just add the version mark to the controller header under the corresponding folder
[ApiVersion(“1”)] [ApiVersion(“2”)] [ApiVersion(“…”)]
The two controllers shown in the figure below

In this way, two versions of UserController The internal codes of specific controllers can be different , And then run Project observation Swagger UI You will find the following figure :

Can pass SwaggerUI Switch between versions in the upper right corner SwaggerDoc

Click on a single interface Try it out There will also be a api-version Field of , Because our side is configured from Header Pass in this parameter, so you can see from the interface that this field is from Header Delivered , If you want to go from url Pass on , Mainly adjust the above register api Version control services The setting over there is from Query Just pass it in .
So far, the basic api The version control logic is complete .
Let's talk about if Part of the project api The controller does not need version control , How to deal with it is universal , Sometimes there are some basic things in a project api It basically won't change , If every time api Version upgrades all It is obviously too cumbersome to upgrade all controllers , So we can mark some global controllers separately .
Just add [ApiVersionNeutral] Just mark it , Added [ApiVersionNeutral] The marked controller indicates that the controller has exited the version control logic , No matter what app What is the version number passed in from the front end , Can normally enter the logic of this control . as follows
[ApiVersionNeutral]
[ApiController]
[Route("api/[controller]")]
public class FileController : ControllerBase
{
}
Another kind is when we api After the version upgrade , We want to mark a api It has been abandoned , You can use Deprecated To represent the version of api Has been eliminated .
[ApiVersion("1", Deprecated = true)]
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
[HttpPost("CreateUser")]
public void CreateUser(DtoCreateUser createUser)
{
// Internal registration logic is omitted here
}
}
Run after adding the obsolescence flag SwaggerUI The following pattern will appear

adopt SwaggerDoc You can clearly see v1 Version of api It has been eliminated .
thus About asp.net core webapi in api The basic operations of version control are explained , Anything you don't understand , You can comment at the bottom of the article or send me a private message , Welcome everyone to actively discuss and Exchange , Interested friends can pay attention to one I am currently maintaining .net Basic framework project https://github.com/berkerdong/NetEngine.git
边栏推荐
- Interface test - process test supports batch parameter import, and the test efficiency is directly full!
- Serein [lazy artifact] a graphical tool that collects URLs in batches and detects the collected URLs in batches. It solves the problem of fishing project
- oracledb_ Exporter monitors Oracle, a very low intrusive monitoring scheme.
- Problems and solutions of wechat applet related knowledge points and cloud music project production
- View CPU information mode
- 【C语言入门】----指针(初阶)
- LOCUST性能测试1(认识)
- Seven sorts (1)
- The head company of the food delivery robot has no money to burn. The official of Purdue technology announced layoffs, and the sales team cut 2/3
- Degree engine (21): jog animation
猜你喜欢

07 BTC mining development related history

stack-protector enabled but compiler support broken

Using docker to build grafana+prometheus monitoring database resources (II)

Go语言指针

Count the age distribution (interval statistics of 5 years old) and draw the age distribution map.
![[Huawei online battle] download and run Huawei's official unity example code, prompting authentication failure and returning error code 100114](/img/32/7d796399ac996fd7da5609f0252dfb.png)
[Huawei online battle] download and run Huawei's official unity example code, prompting authentication failure and returning error code 100114

拼多多关键词搜索接口,商品分类ID搜索商品列表接口,关键词搜索商品销量接口,拼多多销量API接口

微信小程序之网易云音乐的实现-云音乐

dlvm-netcore 開源框架

.NET Core 使用 ImageSharp 生成图片
随机推荐
Count the age distribution (interval statistics of 5 years old) and draw the age distribution map.
dlvm-netcore 开源框架
小工具(读取Excel数据并存入数据库表)
送餐机器人头部公司已无钱可烧,普渡科技官宣裁员,销售团队砍了2/3
mysql库使用中卡死或者死锁事件
PLC approximately calculates the water tank flow (FC) through Bernoulli equation
Suning commodity details API interface (commodity details page data interface)
Pytest+request+allure+excel interface automation from 0 to 1 [four allure test reports]
How to debug the dynamic code generated by C emit?
Implementation of wechat applet Netease cloud music cloud music
Unity 判断物体是否在相机前面以及UI跟随3D物体
Letter combination of leecode17 phone number
淘宝开发平台店铺商品上传接口,店铺订单交易接口,店铺订单解密接口,店铺上下架接口,店铺订单推送接口(整理好的完整店铺上货订单操作接口)
07 BTC mining development related history
Interviewer: how to clean the data of ES cluster regularly
微信公众号开发-自定义菜单
Little red book product details API interface (item_get get get little red book product details interface)
Super sub query implements join query gracefully
Gao Fushui in unit testing, pytest framework (III) use case marking and test execution
Tree array explanation