Swagger大家都不陌生,Swagger (OpenAPI) 是一个与编程语言无关的接口规范,用于描述项目中的 REST API。它的出现主要是节约了开发人员编写接口文档的时间,可以根据项目中的注释生成对应的可视化接口文档。

OpenAPI 规范 (openapi.json)

OpenAPI 规范是描述 API 功能的文档。该文档基于控制器和模型中的 XML属性注释。它是 OpenAPI 流的核心部分,用于驱动诸如 SwaggerUI 之类的工具。

.NET 平台下的两个主要实现Swagger的包是 SwashbuckleNSwag。今天我们从 Swashbuckle 开始了解。

基础功能

1、在包管理器搜索Swashbuckle.AspNetCore并安装。

2、在Startup.cs文件内的ConfigureServices方法内添加代码。
public void ConfigureServices(IServiceCollection services)
{
services.AddControllers();
services.AddSwaggerGen();
}
3、在Startup.cs文件内的Configure方法内添加代码。
app.UseSwagger();
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
options.RoutePrefix = string.Empty;
});
4、修改项目的launchSettings.json文件,将launchUrl的值改为:index.html
5、准备接口
    [ApiController]
public class HomeController : ControllerBase
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
} /// <summary>
/// 获取用户信息
/// </summary>
/// <returns></returns>
[HttpGet("home/getuser")]
public string GetUser()
{
return "my name is dotnetboy";
} /// <summary>
/// 登录成功
/// </summary>
/// <returns></returns>
[HttpPost("home/login")]
public string Login()
{
return "login success";
} /// <summary>
/// 删除用户
/// </summary>
[HttpDelete("home/{id}")]
public string DeleteUser(string id)
{
return $"delete success,id={id}";
}
}
6、开启xml文档输出然后启动项目

扩展功能

项目描述

services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "测试接口文档",
Version = "v1",
Description = "测试 webapi"
});
});

接口分组

在实际开发中,如果所有接口都展示在一起非常不利于相关人员查找,我们可以根据业务逻辑对相关接口进行分组,比如:登录、用户、订单、商品等等。

1、准备分组信息特性
/// <summary>
/// 分组信息特性
/// </summary>
public class GroupInfoAttribute : Attribute
{
/// <summary>
/// 标题
/// </summary>
public string Title { get; set; }
/// <summary>
/// 版本
/// </summary>
public string Version { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
}
2、准备分组枚举
/// <summary>
/// 接口分组枚举
/// </summary>
public enum ApiGroupNames
{
[GroupInfo(Title = "登录认证", Description = "登录相关接口", Version = "v1")]
Login,
[GroupInfo(Title = "User", Description = "用户相关接口")]
User,
[GroupInfo(Title = "User", Description = "订单相关接口")]
Order
}
3、准备接口特性
/// <summary>
/// 分组接口特性
/// </summary>
public class ApiGroupAttribute : Attribute, IApiDescriptionGroupNameProvider
{
/// <summary>
///
/// </summary>
/// <param name="name"></param>
public ApiGroupAttribute(ApiGroupNames name)
{
GroupName = name.ToString();
}
/// <summary>
/// 分组名称
/// </summary>
public string GroupName { get; set; }
}
4、给不同接口加上特性
[ApiController]
public class HomeController : ControllerBase
{
private readonly ILogger<HomeController> _logger;
public HomeController(ILogger<HomeController> logger)
{
_logger = logger;
}
/// <summary>
/// 获取用户信息
/// </summary>
/// <returns></returns>
[HttpGet("home/getuser")]
[ApiGroup(ApiGroupNames.User)]
public string GetUser()
{
return "my name is dotnetboy";
}
/// <summary>
/// 登录成功
/// </summary>
/// <returns></returns>
[HttpPost("home/login")]
[ApiGroup(ApiGroupNames.Login)]
public string Login()
{
return "login success";
}
/// <summary>
/// 删除订单
/// </summary>
[HttpDelete("home/{id}")]
[ApiGroup(ApiGroupNames.Order)]
public string DeleteOrder(string id)
{
return $"delete success,id={id}";
}
/// <summary>
/// 留言
/// </summary>
[HttpDelete("home/message")]
public string DeleteUser(string msg)
{
return $"message:{msg}";
}
}
5、修改 ConfigureServices 方法的 AddSwaggerGen
services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "接口文档",
Version = "v1",
Description = "测试 webapi"
}); // 遍历ApiGroupNames所有枚举值生成接口文档,Skip(1)是因为Enum第一个FieldInfo是内置的一个Int值
typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
{
//获取枚举值上的特性
var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
options.SwaggerDoc(f.Name, new OpenApiInfo
{
Title = info?.Title,
Version = info?.Version,
Description = info?.Description
});
});
// 没有特性的接口分到NoGroup上
options.SwaggerDoc("NoGroup", new OpenApiInfo
{
Title = "无分组"
});
// 判断接口归于哪个分组
options.DocInclusionPredicate((docName, apiDescription) =>
{
if (docName == "NoGroup")
{
// 当分组为NoGroup时,只要没加特性的接口都属于这个组
return string.IsNullOrEmpty(apiDescription.GroupName);
}
else
{
return apiDescription.GroupName == docName;
}
});
});
6、修改 Configure 方法的 UseSwaggerUI
app.UseSwaggerUI(options =>
{
// 遍历ApiGroupNames所有枚举值生成接口文档
typeof(ApiGroupNames).GetFields().Skip(1).ToList().ForEach(f =>
{
//获取枚举值上的特性
var info = f.GetCustomAttributes(typeof(GroupInfoAttribute), false).OfType<GroupInfoAttribute>().FirstOrDefault();
options.SwaggerEndpoint($"/swagger/{f.Name}/swagger.json", info != null ? info.Title : f.Name);
});
options.SwaggerEndpoint("/swagger/NoGroup/swagger.json", "无分组");
options.RoutePrefix = string.Empty;
});

自定义UI

前几天,前端同事和我吐槽,Swagger的原生UI太丑了,又不够直观,想找个接口还得一个个收缩展开,总之就是很难用。

  1. 不够直观
  2. 不方便查找

有了上面的两点需求何不自己实现一套UI呢?(最终还是用了第三方现成的)

文章最开始有提到OpenAPI 对应的 json 内容,大家也可以在浏览器的控制台看看,swagger ui 的数据源都来自于一个叫 swagger.json 的文件,数据源都有了,根据数据源再做一套 UI 也就不是什么难事了。

1、准备一个美观的单页面(网上找的)

2、将单页面相关内容放到项目内(记得开启静态文件读取)
app.UseStaticFiles();

3、将单页面指定为 UI 页面。
app.UseSwaggerUI(options =>
{
options.IndexStream = () => GetType().Assembly.GetManifestResourceStream("h.swagger.Swagger.index.html");
});
4、在单页面内处理 swagger.json 数据源。
5、最终效果

Swagger UI的功能还是比较多的,比如:详情调试。如果想自己实现一套UI要做的工作还很多。所以,拿来主义永不过时,最终我还是选择了第三方开源的项目:Knife4j

使用起来也是非常简单,先引用包:IGeekFan.AspNetCore.Knife4jUI,然后在Startup.Configure中将 app.UseSwaggerUI 替换为:

app.UseKnife4UI(c =>
{
c.RoutePrefix = string.Empty;
c.SwaggerEndpoint($"/swagger/v1/swagger.json", "h.swagger.webapi v1");
});

.NET Core基础篇之:集成Swagger文档与自定义Swagger UI的更多相关文章

  1. 利用typescript生成Swagger文档

    项目地址:https://github.com/wz2cool/swagger-ts-doc demo代码地址:https://github.com/wz2cool/swagger-ts-doc-de ...

  2. Core + Vue 后台管理基础框架8——Swagger文档

    1.前言 作为前后端分离的项目,或者说但凡涉及到对外服务的后端,一个自描述,跟代码实时同步的文档是极其重要的.说到这儿,想起了几年前在XX速运,每天写完代码,还要给APP团队更新文档的惨痛经历.给人家 ...

  3. SpringBoot系列:六、集成Swagger文档

    本篇开始介绍Api文档Swagger的集成 一.引入maven依赖 <dependency> <groupId>io.springfox</groupId> < ...

  4. asp.net core web api 生成 swagger 文档

    asp.net core web api 生成 swagger 文档 Intro 在前后端分离的开发模式下,文档就显得比较重要,哪个接口要传哪些参数,如果一两个接口还好,口头上直接沟通好就可以了,如果 ...

  5. Asp.Net Core基础篇之:白话管道中间件

    在Asp.Net Core中,管道往往伴随着请求一起出现.客户端发起Http请求,服务端去响应这个请求,之间的过程都在管道内进行. 举一个生活中比较常见的例子:旅游景区. 我们都知道,有些景区大门离景 ...

  6. asp.net core 2.1 生成swagger文档

    新建asp.netcore2.1 api项目 “WebApplication1” 在nuget管理器中添加对Swashbuckle.AspNetCore 3.0.0.Microsoft.AspNetC ...

  7. 使用.NET 6开发TodoList应用(27)——实现API的Swagger文档化

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 在日常开发中,我们需要给前端提供文档化的API接口定义,甚至需要模拟架设一个fake服务用来调试接口字段.或者对于后端开发人员 ...

  8. 使用 Swagger 文档化和定义 RESTful API

    大部分 Web 应用程序都支持 RESTful API,但不同于 SOAP API——REST API 依赖于 HTTP 方法,缺少与 Web 服务描述语言(Web Services Descript ...

  9. Springboot 系列(十六)你真的了解 Swagger 文档吗?

    前言 目前来说,在 Java 领域使用 Springboot 构建微服务是比较流行的,在构建微服务时,我们大多数会选择暴漏一个 REST API 以供调用.又或者公司采用前后端分离的开发模式,让前端和 ...

随机推荐

  1. 你知道如何从单片机过渡到嵌入式linux需要经历那些吗?(这个亲身体验有效)

    就现在的行业发展来看只会单片机已经不吃香了并且在薪资待遇方面来看的话单片机的收入限制性太强可能工作很多年之后发现没有了成长空间,因此逐渐转到嵌入式Linux这个方向是越来越多的人的一个选择,那么接触了 ...

  2. 一文带你掌握【TCP拥塞窗口】原理

    ❝ 关注公众号:高性能架构探索.后台回复[资料],可以免费领取 ❞ 学过网络相关课程的,都知道TCP中,有两个窗口: 滑动窗口(在我们的上一篇文章中有讲),接收方通过通告发送方自己的可以接受缓冲区大小 ...

  3. 攻防世界 web1.view_source

    右键不管用,F12打开控制台,直接查看flag.

  4. 阿里P7面试官:请你简单说一下类加载机制的实现原理?

    面试题:类加载机制的原理 面试官考察点 考察目标: 了解面试者对JVM的理解,属于面试八股文系列. 考察范围: 工作3年以上. 技术背景知识 在回答这个问题之前,我们需要先了解一下什么是类加载机制? ...

  5. C/C++如何传递二维数组?

    用二维数组作为参数传递(用二维数组处理矩阵),但是希望接受传递二维数组参数的函数可以处理任意维度的数组(希望矩阵的行数和列数都是不固定的). ----------------------------- ...

  6. 力扣 - 剑指 Offer 58 - I. 翻转单词顺序

    题目 剑指 Offer 58 - I. 翻转单词顺序 思路1 假如题目要求我们翻转字符串,那么我们可以从末尾往前开始遍历每一个字符,同时将每一个字符添加到临时空间,最后输出临时空间的数据就完成翻转了, ...

  7. 【linux命令】 磁盘管理

    du du是查看硬盘的使用情况,统计文件或目录的空间大小. -a 显示所有目录或文件的大小 -b 以byte为单位,显示目录或文件的大小 -c 显示目录或文件的总和 -k 以KB为单位输出 -m 以M ...

  8. SQL里ORDER BY 对查询的字段进行排序,字段为空不想排在最前

    在安字段排序时 空字段往往都是在最前,我只是想空字段在排序的后面,不为空的在前,这个如何修改呢 order by datatime desc   这样的句子也一样  不管是正排还是倒排  为空的都在最 ...

  9. Flask搭建弹幕视频网站(1)

    说在前面 也不知道最后能不能完成网站,所以就想把这十多天来学习到的点点滴滴记录下来.学的越来越多,所谓全栈也是需要前端基础,越来越感受到压力,但是遇到一个问题就解决一个问题,慢慢习惯之后感觉也还行.说 ...

  10. vue + cesium开发(3) cesium1.87更新问题

    官方在2021年11月1号更新日志中记录了他们把zip.js升级到了2.3.12以适应webpack4中的关于import.meta不兼容的语法问题,但是经过实测,1.87版本依然没有解决这个问题,所 ...