zoukankan      html  css  js  c++  java
  • ASP.NET Core – Web API Versioning

    前言

    项目持续维护, API 就需要版本控制. ASP.NET Core 有官方的插件专门处理 API 版本控制哦.

    主要参考

    Your Guide to REST API Versioning in ASP.NET Core

    Asp.Net.Core WebApi 4种版本控制的方式

    How to use API versioning in ASP.NET Core

    ASP.NET Core WebApi版本控制的实现 (有讲到 swagger 哦)

    Asp.Net Core 5 - API Versioning

    Github aspnet-api-versioning

    安装 nuget

    dotnet add package Microsoft.AspNetCore.Mvc.Versioning

    Program.cs

    using Microsoft.AspNetCore.Mvc;
    
    var builder = WebApplication.CreateBuilder(args);
    builder.Services.AddControllers();
    builder.Services.AddEndpointsApiExplorer();
    builder.Services.AddApiVersioning(options =>
    {
        options.AssumeDefaultVersionWhenUnspecified = true; // 如果请求没有声明就使用默认版本
        options.DefaultApiVersion = new ApiVersion(1, 0); // 默认版本
        options.ReportApiVersions = true; // 在 header 返回支持的版本 (尤其用于 deprecated 弃用的 API)
    });
    //builder.Services.AddSwaggerGen();
    var app = builder.Build();
    if (app.Environment.IsDevelopment())
    {
        //app.UseSwagger();
        //app.UseSwaggerUI();
    }
    app.UseHttpsRedirection();
    app.UseAuthorization();
    app.MapControllers();
    app.Run();

    这个是 ASP.NET Core 6.0 的版本哦, 主要看 .AddApiVersioning, Swagger 我注释掉是因为 versioning 和 swagger 有时候会打架. 

    By default, 它是用 request query string 声明 version 的, 这个通常我们不喜欢,我们喜欢在 url path 里面声明. 最好也不要有 default version 的概念. 因为竟然都分 version 了咯, 就分清清楚楚丫.

    两种管理方式

    1. 一个 controller 多个 version 

    namespace WebApiVersioning.Controllers
    {
        [ApiController]
        // 表示这个 Controller 支持 1.0 和 2.0
        [ApiVersion("1.0", Deprecated = true)] // Deprecated 表示废弃了, 会在返回的 header 表示, 虽然是废弃了, 但是依然会跑和 response 的哦 (自行处理)
        [ApiVersion("2.0")]
        [Route("api/v{version:apiVersion}/[controller]")] // 声明 version in path
        public class WeatherForecastController : ControllerBase
        {
            [HttpGet(Name = "GetWeatherForecast"), MapToApiVersion("1.0")] // 通过 MapToApiVersion 声明这个 action 是 for 哪个 version 
            public IEnumerable<WeatherForecast> Get_v1() // 名字是 v1
            {
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
                .ToArray();
            }
    
            [HttpGet(Name = "GetWeatherForecast"), MapToApiVersion("2.0")]
            public IEnumerable<WeatherForecast> Get_v2() // 名字是 v2
            {
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
                .ToArray();
            }
    
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
        }
    }

    把多个 version 放 1 个 controller 会和 swagger 打架哦 (因为 swagger 不允许 action same path), 虽然很方便但是我觉得可能不顺风水哦.

    请求 v1.0 就会执行 Get_v1, v2.0 就是 Get_v2

    header response 都会表示 api-supported-versions 和 api-deprecated-versions (如果有).

    如果都没有 deprecated, 会这样

    2. 1 个 controller 一个 version

    通过 namespace 来区分 version, 或者通过 controller 不同名字来做 version 也是可以的. 

    namespace WebApiVersioning.Controllers.v1
    {
        [ApiController]
        [ApiVersion("1.0")]
        [Route("api/v{version:apiVersion}/[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            [HttpGet(Name = "GetWeatherForecast")] 
            public IEnumerable<WeatherForecast> Get()
            {
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
                .ToArray();
            }
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
        }
    }
    namespace WebApiVersioning.Controllers.v2
    {
        [ApiController]
        [ApiVersion("2.0")]
        [Route("api/v{version:apiVersion}/[controller]")]
        public class WeatherForecastController : ControllerBase
        {
            [HttpGet(Name = "GetWeatherForecast")]
            public IEnumerable<WeatherForecast> Get()
            {
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = Random.Shared.Next(-20, 55),
                    Summary = Summaries[Random.Shared.Next(Summaries.Length)]
                })
                .ToArray();
            }
          
            private static readonly string[] Summaries = new[]
            {
                "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
            };
        }
    }

    Non-version

    有些 API 不需要 version control 的话, 用这个 attribute 就可以了

    [ApiVersionNeutral]
  • 相关阅读:
    Mysql蠕虫复制
    Mysql中如何开启慢查询功能?
    线程的状态以及状态切换
    Java的Unsafe类
    Spring 获取jar内外文件的方式
    RocketMQ学习
    volatile的理解
    快速排序
    JVM的发展史
    nginx安装配置
  • 原文地址:https://www.cnblogs.com/keatkeat/p/15458269.html
Copyright © 2011-2022 走看看