• Oh my God, Swagger API文档竟然可以这样写?


    最好的总会在不经意间出现。

    作为后端程序员,免不了与前端同事对接API, 一个书写良好的API设计文档可有效提高与前端对接的效率。

    为避免联调时来回撕逼,今天我们聊一聊正确使用Swaager的姿势。

    基础Swagger用法

    ConfigureServices配置Swagger文档,在Configure启用中间件

     // Install-Package Swashbuckle.AspNetCore 略 
     services.AddSwaggerGen(
           options =>
           {
               options.SwaggerDoc("v1", new OpenApiInfo { Title = "EAP API", Version = "v1" });
           }
      );     
    ---
    
    app.UseSwagger();
    app.UseSwaggerUI(options =>
    {
        options.SwaggerEndpoint("/swagger/v1/swagger.json", "EAP API");
    });
    

    应用会在/Swagger页面加载最基础的API文档。

    以一个最简单的Post请求为例,细数这最基础SwaggerUI的弊病

    [HttpPost]
    public async Task<bool> AddHotmapAsync([FromBody] CreateHotmapInput createHotmapInput)
    {
         var model = ObjectMapper.Map<CreateHotmapInput, Hotmap>(createHotmapInput);
         model.ProfileId = CurrentUser.TenantId;
         return await _hotmaps.InsertAsync(model)!= null;
    }
    

    产生如图示SwaggerUI:

    1. Post请求的Payload字段值相对复杂,竟不给前端传值example?
    2. 没有指示前端请求的Content-Type,前端会不会给你另外一个surprise?
    3. 服务器没有指示响应的Content-Type,?
    4. 服务器没有指示响应的预期状态码,前端会不会抓狂?

    下文就来根治这些顽疾, 书写一个自述性、优雅的API文档。

    Swagger最佳实践

    三下五除二,给出示例:

            /// <summary>
            /// 添加热力图
            /// </summary>
            /// <remarks>
            /// Sample request:
            /// ```
            ///  POST /hotmap
            ///  {
            ///      "displayName": "演示名称1",
            ///      "matchRule": 0,
            ///      "matchCondition": "https://www.cnblogs.com/JulianHuang/",
            ///      "targetUrl": "https://www.cnblogs.com/JulianHuang/",
            ///      "versions": [
            ///      {
            ///         "versionName": "ver2020",
            ///         "startDate": "2020-12-13T10:03:09",
            ///         "endDate": "2020-12-13T10:03:09",
            ///          "offlinePageUrl": "3fa85f64-5717-4562-b3fc-2c963f66afa6",  //  没有绑定图片和离线网页的对应属性传 null
            ///          "pictureUrl": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
            ///          "createDate": "2020-12-13T10:03:09"
            ///      }
            ///    ]
            ///  }
            ///```
            /// </remarks>
            /// <param name="createHotmapInput"></param>
            /// <returns></returns>
            [Consumes("application/json")]
            [Produces("text/plain")]
            [ProducesResponseType(typeof(HotMap), 200)]
            [HttpPost]
            public async Task<bool> AddHotmapAsync([FromBody] CreateHotmapInput createHotmapInput)
            {
                var model = ObjectMapper.Map<CreateHotmapInput, Hotmap>(createHotmapInput);
                model.ProfileId = CurrentUser.TenantId;
                await _hotmaps.InsertAsync(model);
                return "done !, This is Test";
            }
    
    1. 通过给API添加XML注释

    注意如果注释内容包含代码,可以使用Markdown的代码语法```,在注释里面优雅显示代码.

    1. 通过Consumes,Produces特性指示action接收和返回的数据类型,也就是媒体类型。

    Consumes、Produces是指示请求/响应支持的content types的过滤器,位于Microsoft.AspNetCore.Mvc命名空间下。

    1. 通过ProducesResponseType特性指示服务器响应的预期内容和状态码

    API文档结果:

    这样的SwaggerUI才正确表达了后端程序员的内心输出。


    在Swagger文档上显示注释

    1. 生成XML注释文档
      在项目上[右键]-[属性]-[生成标签页]-[勾选XML文档文件];
      或者直接在项目csproj文件--[PropertyGroup]添加<GenerateDocumentationFile>true</GenerateDocumentationFile>
    2. AddSwaggerGen方法添加下行,启用注释文件
    // Set the comments path for the Swagger JSON and UI.
    var xmlFile = $"{this.GetType().Assembly.GetName().Name}.xml";
    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    opt.IncludeXmlComments(xmlPath);
    

    这里啰嗦一下,如果是Abp Vnext解决方案(API是定义在HttpApi项目/Application项目),故我们要为Abp Vnext解决方案加载带xml注释的Swagger Json,需要指示xmlFile为HttpApi.xml或者applicaiton.xml

    以上就是小码甲总结的书写Swagger文档的优雅姿势:

    • 编写API 传值example
    • 约束请求/响应 支持的媒体类型
    • 指示API的预期输出内容、预期状态码

    API自述,约束输入输出,前端同事再也不会追着你撕逼了!

  • 相关阅读:
    Football Foundation (FOFO) TOJ 2556
    JAVA- String类练习
    JAVA- 清除数组重复元素
    Mysql远程登陆错误:ERROR 2003
    Linux学习之路(五)压缩命令
    Linux学习之路(四)帮助命令
    如何识别真Microsoft服务与非Microsoft服务来定位病毒自己的服务
    如何用命令行删除EasyBCD开机选择项?
    JAVA- 成员变量与局部变量的区别
    JAVA- 内部类
  • 原文地址:https://www.cnblogs.com/JulianHuang/p/14131203.html
Copyright © 2020-2023  润新知