• ASP.NET Core 3.0 实战:构建多版本 API 接口


    第一次在博客写分享,请多多捧场,如有歧义请多多包含!
    因为业务需求发展需要,所以API接口的变更升级是必不可少的事情,而原有的接口是不可能马上停止使用的。例如:Login接口为例,1.0版本之返回用户的基本信息,而2.0版本的迭代下,要把用户祖宗十八代信息都要返回到客户端,这时候1.0 vs 2.0版本的返回信息有一点信息上的差异,如果在不进行版本控制的情况下,在原1.0的版本下优化,那么会出现一个比较严重的问题,如果还有在使用原1.0版本的终端岂不是GG了,所以如何能鱼与熊掌兼得,同时为1.0、2.0版本的终端考虑,所以一般常见的几种解决方案如下:
     
    1、使用不同API名称(常见同时最为恶心)
    这种是非常简单粗暴,非灵活处理方案,例如:1.0=Login 2.0=NewLogin 相对于来说是可以有效兼顾到各版本的终端用户,但是还是不够灵活,可配置度有点低。
    1.0版本 https://****.com/Login
    2.0版本 https://****.com/NewLogin
    2、请求时带参数(这里就不详细说了)
    1.0版本 https://****.com/Login?version=1
    2.0版本 https://****.com/Login?version=2
    3、Header中标识版本信息
    终端调用API接口时,在Header中添加参数来表明请求的版本信息
    4、在URL中标识版本信息
    1.0版本 https://****.com/v1/Login
    2.0版本 https://****.com/v2/Login
     
    这里主要介绍的是第四种方案的项目搭建(网上有很多类似的文章描述)
     
    1、建立web api项目
     
    2、NuGet集成以下组件
    SwashBuckle.AspNetCore 4.0.1
    Microsoft.AspNetCore.Mvc.Versioning 3.1.1
    Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer 3.1.0
    Microsoft.Extensions.PlatformAbstractions1.1.0 (选择性集成,如果不需要API XMl文档生成的可以去除)
    以上组件的描述、作用请各位google、baidu下去了解,这里不详细说明了
     
    3、项目、代码上的设置/改动
    在Startup->ConfigureServices方法中添加以下代码
           services.AddApiVersioning((o) =>
                {
                    o.ReportApiVersions = true;//可选配置,设置为true时,header返回版本信息
                    o.DefaultApiVersion = new ApiVersion(1, 0);//默认版本,请求未指明版本的求默认认执行版本1.0的API
                    o.AssumeDefaultVersionWhenUnspecified = true;//是否启用未指明版本API,指向默认版本
                }).AddVersionedApiExplorer(option =>
                {
                    option.GroupNameFormat = "'v'VVVV";//api组名格式
                    option.AssumeDefaultVersionWhenUnspecified = true;//是否提供API版本服务
                }).AddSwaggerGen((s) =>
                {
                    //填充UI内容
                    var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        s.SwaggerDoc(description.GroupName,
                             new Info()
                             {
                                 Title = $"体检微服务接口 v{description.ApiVersion}",
                                 Version = description.ApiVersion.ToString(),
                                 Description = "微服务框架-切换版本请点右上角版本切换",
                                 Contact = new Contact() { Name = "荣少(黎更荣) WeChat:186***** QQ:157537648", Email = "*******@hotmail.com" }
                             }
                        );
                    }
                    //生成API XML文档
                    var basePath = PlatformServices.Default.Application.ApplicationBasePath;
                    var xmlPath = Path.Combine(basePath, typeof(Startup).GetTypeInfo().Assembly.GetName().Name + ".xml");
                    s.IncludeXmlComments(xmlPath);
                });

    以上代码其中option.GroupNameFormat = "'v'VVVV";//api组名格式,各位可以尝试玩玩~~~~

    在Startup->Configure方法中添加以下代码

                app.UseSwagger().UseSwaggerUI((o) =>
                {
                    foreach (var description in provider.ApiVersionDescriptions)
                    {
                        o.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
                    }
                });

    其中在Startup->Configure方法中缺少了IApiVersionDescriptionProvider provider参数,自己手动补上即可

    //项目自动生成的版本
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    
    //参数补上后的版本 
    public void Configure(IApplicationBuilder app, IHostingEnvironment env, IApiVersionDescriptionProvider provider)

    以上配置基本上算时完成了,那么Web Api要怎么写法呢?

    在WebApi项目中Controllers下建立v1、v2俩个文件夹

    namespace WebApplication1.Controllers.v1
    {
        [ApiVersion("1.0")]
        [Route("api/v{version:apiVersion}/[controller]")]
        [ApiController]
        public class ValuesController : ControllerBase
        {
            [HttpGet]
            public ActionResult<IEnumerable<string>> Get()
            {
                return new string[] { "v1", "v1" };
            }
        }
    }
    namespace WebApplication1.Controllers.v2
    {
        [ApiVersion("2.0")]
        [Route("api/v{version:apiVersion}/[controller]")]
        [ApiController]
        public class ValuesController : ControllerBase
        {
            [HttpGet]
            public ActionResult<IEnumerable<string>> Get()
            {
                return new string[] { "v2", "v2" };
            }
        }
    }

    这里的路由设置了配置的标签{version:apiVersion},其中ApiVersion中有各类的属性字段,例如:弃用(不代表停用,就好像巨硬上已经过时的方法)该版本API-ApiVersion("1.0", Deprecated = true)],该[ApiVersionNeutral]标签就是表明停用,不需要该版本。

    配置完成后,可以直接用url访问不同版本的接口地址:

    https://localhost:44383/api/v1/Values

    https://localhost:44383/api/v2/Values

    最后的配置,因为项目默认启动的是api/Values接口地址,需要修改项目Properties->launchSettings.json

    最终运行效果如下:

     2019-10-21  博客园网友反馈的问题

    1、运行不成功的项目是 @化身孤岛的蓝羽  提供的,谢谢!

    2、但是楼主写这篇文章的时候.Net Core  preview 8 / 9忘记了,代码也没有保留

    3、@化身孤岛的蓝羽反馈根据我的文章步骤,生产的项目无法正常运行,错误:

    是不是有点懵了,我也懵了,但是不要放弃,方法总比困难多,根据上面的提示,度娘下,更懵没有解决的方案。

    推荐大家用bing、google搜索,这样更加精致。由于微软开源,github上直接看aspnet-api-versioning - Issues,估计

    很多人会遇到你出现的问题。

    其实刚入门的朋友一看,NuGet好像没有这个版本的Microsoft.AspNetCore.Mvc.Versioning,那应该怎么办?

    项目中打开管理NuGet程序包,选择你想要了解的组件

     点击下右上角的nuget.org,你就可以找到你想要的版本号信息

     

    如此类推,如下组件都更新到最新版本

    SwashBuckle.AspNetCore -- 5.0.0-rc4
    Microsoft.AspNetCore.Mvc.Versioning -- 4.0.0-preview8.19405.7
    Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer -- 4.0.0-preview8.19405.7
    Microsoft.Extensions.PlatformAbstractions1.1.0 这个版本没有变更过,所以这次不需要处理
     
    那么版本号都找到了,管理NuGet程序包无法变更为预览最新版本啊....不要着急,找到项目根目录;
    打开你建立项目的****.csproj,用文本格式打开或者直接用vscode打开(这个是博客朋友根据文章无法运行的项目)

    把对应,你想要的版本号替换到Version即可,然后项目会重新加载,你再次运行,还是报错,裴漼不......

    报错原因:

     

    搞掂,运行成功

     如果是对您有帮助,而您又比较慷概的请微信打赏下(后续会有更多的分享):

  • 相关阅读:
    NLP---word2vec的python实现
    matplotlib---Annotation标注
    matplotlib---legend图例
    matplotlib---设置坐标轴
    windows下右键新建md文件
    vue+webpack+npm 环境内存溢出解决办法
    element-ui tree树形组件自定义实现可展开选择表格
    vue-动态验证码
    ES6 数组函数forEach()、map()、filter()、find()、every()、some()、reduce()
    eslint配置文件规则
  • 原文地址:https://www.cnblogs.com/vcode/p/10225410.html
Copyright © 2020-2023  润新知