zoukankan      html  css  js  c++  java
  • ASP.NET Core WebApi版本控制

    前言:

     在日常项目开发中,随着项目需求不断的累加、不断的迭代;项目服务接口需要向下兼容历史版本;前些时候就因为Api接口为做版本管理导致接口对低版本兼容处理不友好。

     最近就像了解下如何实现WebApi版本控制,那么版本控制有什么好处呢?

     WebApi版本控制的好处

    • 有助于及时推出功能, 而不会破坏现有系统,兼容性处理更友好。
    • 它还可以帮助为选定的客户提供额外的功能。

     接下来就来实现版本控制以及在Swagger UI中接入WebApi版本

    一、WebApi版本控制实现

      通过Microsoft.AspNetCore.Mvc.Versioning 实现webapi 版本控制

    • 创建WebApi项目,添加Nuget包:Microsoft.AspNetCore.Mvc.Versioning 
    Install-Package Microsoft.AspNetCore.Mvc.Versioning 
    • 修改项目Startup文件,使用Microsoft.AspNetCore.Mvc.Versioning 
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }
        public IConfiguration Configuration { get; }
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            //根据需要设置,以下内容
            services.AddApiVersioning(apiOtions =>
            {
                //返回响应标头中支持的版本信息
                apiOtions.ReportApiVersions = true;
                //此选项将用于不提供版本的请求。默认情况下, 假定的 API 版本为1.0
                apiOtions.AssumeDefaultVersionWhenUnspecified = true;
                //缺省api版本号,支持时间或数字版本号
                apiOtions.DefaultApiVersion = new ApiVersion(1, 0);
                //支持MediaType、Header、QueryString 设置版本号;缺省为QueryString、UrlSegment设置版本号;后面会详细说明对于作用
                apiOtions.ApiVersionReader = ApiVersionReader.Combine(
                    new MediaTypeApiVersionReader("api-version"),
                    new HeaderApiVersionReader("api-version"),
                    new QueryStringApiVersionReader("api-version"),
                    new UrlSegmentApiVersionReader());
            });
            services.AddControllers();
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            app.UseHttpsRedirection();
    
            //使用ApiVersioning
            app.UseApiVersioning();
    app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints
    => { endpoints.MapControllers(); }); } }
    • WebApi设置版本:

      a)通过ApiVersion标记指定指定控制器或方法的版本号;Url参数控制版本(QueryStringApiVersionReader),如下:

    namespace WebAPIVersionDemo.Controllers
    {
        [ApiController]
        [Route("[controller]")]
        //Deprecated=true:表示v1即将弃用,响应头中返回
        [ApiVersion("1.0", Deprecated = true)]
        [ApiVersion("2.0")]public class WeatherForecastController : ControllerBase
        {
            private static readonly string[] Summaries = new[]{"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"};
     
            [HttpGet]
            public IEnumerable<WeatherForecast> Get()
            {
                var rng = new Random();
                return Enumerable.Range(1, 5).Select(index => new WeatherForecast
                {
                    Date = DateTime.Now.AddDays(index),
                    TemperatureC = rng.Next(-20, 55),
                    Summary = $"v1:{Summaries[rng.Next(Summaries.Length)]}"
                })
                .ToArray();
            }        
        }
    }

      通过参数api-version参数指定版本号;调用结果:

      

      b)通过Url Path Segment控制版本号(UrlSegmentApiVersionReader):为控制器添加路由方式如下,apiVersion为固定格式  

    [Route("/api/v{version:apiVersion}/[controller]")]

      调用方式:通过调用路径传入版本号,如:http://localhost:5000/api/v1/weatherforecast

       

      c)通过Header头控制版本号:在Startup中设置(HeaderApiVersionReader、MediaTypeApiVersionReader

    apiOtions.ApiVersionReader = ApiVersionReader.Combine(
                    new MediaTypeApiVersionReader("api-version"),
                    new HeaderApiVersionReader("api-version"));

       调用方式,在请求头或中MediaType中传递api版本,如下:

       

        

    • 其他说明:

        a)ReportApiVersions设置为true时, 返回当前支持版本号(api-supported-versions);Deprecated 参数设置为true表示已弃用,在响应头中也有显示(api-deprecated-versions):

        

        b)MapToApiVersion标记:允许将单个 API 操作映射到任何版本(可以在v1的控制器中添加v3的方法);在上面控制器中添加以下代码,访问v3版本方法

    [HttpGet]
    [MapToApiVersion("3.0")]
    public IEnumerable<WeatherForecast> GetV3()
    {
        //获取版本
        string v = HttpContext.GetRequestedApiVersion().ToString();
        var rng = new Random();
        return Enumerable.Range(1, 1).Select(index => new WeatherForecast
        {
            Date = DateTime.Now.AddDays(index),
            TemperatureC = rng.Next(-20, 55),
            Summary = $"v{v}:{Summaries[rng.Next(Summaries.Length)]}"
        })
        .ToArray();
    }

        

        c)注意事项:

        1、路径中参数版本高于,其他方式设置版本

        2、多种方式传递版本,只能采用一种方式传递版本号

        3、SwaggerUI中MapToApiVersion设置版本不会单独显示    

    二、Swagger UI中版本接入

     1、添加包:Swashbuckle.AspNetCore、Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer   

    //swaggerui 包
    Install-Package Swashbuckle.AspNetCore
    //api版本
    Install-Package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 

     2、修改Startup代码:

    public class Startup
    {
        /// <summary>
        /// Api版本提者信息
        /// </summary>
        private IApiVersionDescriptionProvider provider;
    
        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddControllers();
              
            //根据需要设置,以下内容
            services.AddApiVersioning(apiOtions =>
            {
                //返回响应标头中支持的版本信息
                apiOtions.ReportApiVersions = true;
                //此选项将用于不提供版本的请求。默认情况下, 假定的 API 版本为1.0
                apiOtions.AssumeDefaultVersionWhenUnspecified = true;
                //缺省api版本号,支持时间或数字版本号
                apiOtions.DefaultApiVersion = new ApiVersion(1, 0);
                //支持MediaType、Header、QueryString 设置版本号;缺省为QueryString设置版本号
                apiOtions.ApiVersionReader = ApiVersionReader.Combine(
                        new MediaTypeApiVersionReader("api-version"),
                        new HeaderApiVersionReader("api-version"),
                        new QueryStringApiVersionReader("api-version"),
                        new UrlSegmentApiVersionReader());
            });
    
    
            services.AddVersionedApiExplorer(option =>
            {
                option.GroupNameFormat = "接口:'v'VVV";
                option.AssumeDefaultVersionWhenUnspecified = true;
            });
    
            this.provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
            services.AddSwaggerGen(options =>
            {
                foreach (var description in provider.ApiVersionDescriptions)
                {
                    options.SwaggerDoc(description.GroupName,
                            new Microsoft.OpenApi.Models.OpenApiInfo()
                            {
                                Title = $"接口 v{description.ApiVersion}",
                                Version = description.ApiVersion.ToString(),
                                Description = "切换版本请点右上角版本切换"
                            }
                    );
                }
                options.IncludeXmlComments(this.GetType().Assembly.Location.Replace(".dll", ".xml"), true);
            });
    
        }
    
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            //……    
       
            //使用ApiVersioning
            app.UseApiVersioning();
    
            //启用swaggerui,绑定api版本信息
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                foreach (var description in provider.ApiVersionDescriptions)
                {
                    c.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                }
            });
    
            //……    
        }
    }

     3、运行效果:  

      

    其他: 

     示例地址:https://github.com/cwsheng/WebAPIVersionDemo

  • 相关阅读:
    引用与指针的区别联系
    单链表热点面试题
    C语言实现的单链表
    C语言实现的顺序表
    自己实现的库函数2(memset,memcmp,memcpy,memmove)
    自己实现的库函数1(strlen,strcpy,strcmp,strcat)
    Python文件练习_注册
    Python文件练习_自动生成密码文件
    Python文件练习_读取文件并计算平均分
    Python学习笔记七_文件读写
  • 原文地址:https://www.cnblogs.com/cwsheng/p/14426490.html
Copyright © 2011-2022 走看看