10.1、RESTFul 和 Swagger
RESTFul 风格 和 Swagger 接口文档是现代化多端对接必备要素。
什么是 Web API
WebAPI 是一种用来开发系统间接口、设备接口 API 的技术,基于 Http 协议,请求和返回格式结果默认是 json 格式。
WebAPI 比 WCF 更简单、更通用,比 WebService 更节省流量、更简洁。
什么是 RESTFul 风格
REST,即Representational State Transfer的缩写。直接翻译的意思是"表现层状态转化"。 它是一种互联网应用程序的API设计理念:URL定位资源,用HTTP动词(GET,POST,DELETE,PUT,HEAD)描述操作。
RESTful 架构服务器上每一种资源,比如一个文件,一张图片,一部电影,都有对应的URL地址,如果我们的客户端需要对服务器上的这个资源进行操作,就需要通过HTTP协议执行相应的动作来操作它,比如进行获取,更新,删除。
简单来说,就是URL地址中只包含名词表示资源,使用HTTP动词表示动作进行操作资源。
什么是 Swagger
相信无论是前端还是后端开发,都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力,经常来不及更新。其实无论是前端调用后端,还是后端调用后端,都期望有一个好的接口文档。但是这个接口文档对于程序员来说,就跟注释一样,经常会抱怨别人写的代码没有写注释,然而自己写起代码起来,最讨厌的,也是写注释。所以仅仅只通过强制来规范大家是不够的,随着时间推移,版本迭代,接口文档往往很容易就跟不上代码了。
发现了痛点就要去找解决方案。解决方案用的人多了,就成了标准的规范,这就是Swagger的由来。
通过这套规范,你只需要按照它的规范去定义接口及接口相关的信息。再通过Swagger衍生出来的一系列项目和工具,就可以做到生成各种格式的接口文档,生成多种语言的客户端和服务端的代码,以及在线接口调试页面等等。
这样,如果按照新的开发模式,在开发新版本或者迭代版本的时候,只需要更新Swagger描述文件,就可以自动生成接口文档和客户端服务端代码,做到调用端代码、服务端代码以及接口文档的一致性。
所以,Swagger 是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。
总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法、参数和模型紧密集成到服务器端的代码,允许 API 来始终保持同步。Swagger 让部署管理和使用功能强大的 API 从未如此简单。
简单来说,就是解决 RESTFul api 没有详细规范化的对接文档的痛点。
生成RESTFul 风格的Web API
在这现代化的应用开发过程中,最尤为突出的开发模式便是 前后端分离 技术及 MVVM 双向绑定开发模式。而支撑它们的正式 RESTFul 风格的盛行及规范化的对接方式。
所以,Hoa Framework 框架提供了非常强大且易配置的 RESTFul 风格生成引擎。
在 Hoa Framework 支持两种方式生成 RESTFul 风格的API方式,一种是 ASP.NET Core 内置的 ControllerBase
控制器方式,一种是 框架内自实现的 动态控制器服务 方式。
ControllerBase 方式
ASP.NET Core 内置的 ControllerBase
方式只需要在 Hoa.Web.Host.Controllers
目录中定义即可,如:
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace Hoa.Web.Host.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class HoaController : ControllerBase
{
[HttpGet]
[Route(nameof(Author))]
public string Author()
{
return "Powered by Monk";
}
[HttpGet]
[Route(nameof(Name))]
public IActionResult Name()
{
return Content("Hoa");
}
[HttpPost]
[Route("GetDatas/{keyword}")]
public IEnumerable<object> GetDatas([Required] string keyword)
{
// TODO
return null;
}
}
}
框架内部也对ASP.NET Core 内置的 Web API模式做了加强,支持Swagger文档生成、多应用权限、文档分类等强大的功能。
更多 ASP.NET Core RESTFul 风格 WebAPI 方式可查看官方文档。
动态控制器服务 方式(推荐)
动态控制器服务是 Hoa Framework 一项非常强大的功能,大大提升了我们开发的速度和避免了很多配置WebAPI 的常见低级错误。既兼容了 ASP.NET Core 内置的 Web API模式 而且支持Swagger文档生成、多应用权限、文档分类等强大的功能,页提供了非常强大的拦截器操作。是目前构建 WebAPI首选方式。
只需要在 普通服务 类声明地方贴 [HoaServiceController]
特性,并继承 IAppServiceDependency
即可。
默认情况下,动态控制器服务 会将 所有公开的实例方法生成对应的控制器Action,但不会对私有方法和静态方法做生成操作。
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceController] // 贴了特性,动态控制器服务
public class TestAppService : ITestnAppService, IAppServiceDependency // 继承了 IAppServiceDependency
{
// 普通服务
privde readonly ISomeService _service;
privde readonly ISomeService _service2;
public TestAppService(ISomeService service, ISomeService service2)
{
_service = service;
_service2 = service;
}
// Other Codes
}
}
🏴 示例二,手动配置实例方法不生成对应的控制器Action
只需要在方法申明顶部贴 [HoaNonServiceWebApi]
或 [HoaServiceWebApiExplorer(false)]
即可,如:
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceController] // 贴了特性,动态控制器服务
public class TestAppService : ITestAppService, IAppServiceDependency // 继承了 IAppServiceDependency
{
public TestAppService()
{
}
// 会生成控制器对应的Action
public string GetName(){
return "Hoa";
}
// 不会生成控制器对应的Action
[HoaNonServiceWebApi]
public string NoExportGetName(){
return "No Export";
}
// 不会生成控制器对应的Action
[HoaServiceWebApiExplorer(false)]
public string NoExportGetName2(){
return "No Export";
}
}
}
注意:如果在类上面贴[HoaNonServiceWebApi]
或 [HoaServiceWebApiExplorer(false)]
,则这个类的所有方法包含自身都不会生成对应的控制器实例。
🏴 示例三,配置Http Method生成特定请求的控制器Action
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceController] // 贴了特性,动态控制器服务
public class TestAppService : ITestAppService, IAppServiceDependency // 继承了 IAppServiceDependency
{
public TestAppService()
{
}
[HttpGet]
public string GetName(){
return "Hoa";
}
[HttpPost]
public string Create(){
// TODO
}
[HttpPut]
public string Update(){
// TODO
}
[HttpDelete]
public string Delete(){
// TODO
}
[AcceptVerbs("GET","POST")]
pub string GetOrPost(){
// TODO
}
}
}
默认情况下,Hoa Framework 内置了一套生成 HTTP Method 谓词的方法,生成规则如下:
方法名首单词
生成对应的HTTP Method 谓词
add/Add
[HttpPost]
create/Create
[HttpPost]
post/Post
[HttpPost]
insert/Insert
[HttpPost]
get/Get
[HttpGet]
find/Find
[HttpGet]
fetch/Fetch
[HttpGet]
query/Query
[HttpGet]
update/Update
[HttpPut]
put/Put
[HttpPut]
delete/Delete
[HttpDelete]
remove/Remove
[HttpDelete]
缺省
[HttpPost]
🏴 示例四,设置方法已过时
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceController] // 贴了特性,动态控制器服务
public class TestAppService : ITestAppService, IAppServiceDependency // 继承了 IAppServiceDependency
{
public TestAppService()
{
}
// 提示接已过时
[Obsolete("请调用/api/Test/GetWithPost接口")]
pub string GetOrPost(){
// TODO
}
}
}
🏴 示例五,配置URL路由地址
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceController] // 贴了特性,动态控制器服务
public class TestAppService : ITestAppService, IAppServiceDependency // 继承了 IAppServiceDependency
{
public TestAppService()
{
}
[Route("/api/Groups/GetPost")]
pub string GetOrPost(){
// TODO
}
}
}
可以通过 [Route(url)]
方式覆盖默认生成的路由,默认生成的路由格式为:/api/{区域}/{类名}/{方法名}/{值类型参数}
详细大家看到这里的时候已经很清楚了,动态控制器服务 实际和 ControllerBase
的实现方式非常类似,没错,动态控制器服务 就是将我们的 普通服务 变成了 ApiController
,此时共享 ControllerBase
支持的所有功能和特性。
Swagger 功能配置
通过上面第二小节 什么是 Swagger 我们已经了解了 Swagger 的用处,在 Hoa Framework 框架中,除了 Swagger 自带的功能之外,还拓展了很多非常方便而且具有特殊的功能,比如 数据验证、多系统应用授权、多文档分组、性能分析等等。
在 Hoa Framework 中,默认已经启用了 Swagger 功能的支持,也就是无需手动配置。再者,我们只需要简单的贴特性的方式就可以生成非常丰富的 RESTFul 风格的文档了!
文档默认地址
Swagger 默认的文档链接地址是在域名的根目录下,如:https://你的主机/
。

设置文档信息
设置文档信息只需要修改 appsetting.json
HoaSwaggerOptions
节点即可,如果文档有多个分类,只需要在当前节点的 Groups
节点中添加多个分类信息即可。如:
"HoaSwaggerOptions": {
"DocumentTitle": "Hoa RESTFul API", // 文档浏览器标题
"SecurityDefinitionName": "Bearer", // 默认JWT 验证方式 Bearer
"UnClassifiedName": "Default", // 未分类文档默认分组名称
"IsShowMSTestSummary": true, // 是否显示单元测试汇总
"Groups": { // 分类文档信息配置,支持多个,Key 为分类分组名称,如:Default,AuthServer
// 默认分类文档分组名
"Default": {
"Title": "Default API", // 分类标题
"Description": "This is default restful api description.", // 分类描述
"TermsOfService": "", // 协议信息
"Contact": { // 联系方式
"Name": "Monk", // 联系人
"Email": "monksoul@outlook.com", // 联系人电子邮件
"Url": "" // 联系人个人主页
},
"License": { // 许可证
"Name": "", // 许可证名称
"Url": "" // 许可证Url
}
},
// 自定义分组名
"AuthServer": {
"Title": "AuthServer API", // 分类标题
"Description": "This is authServer restful api description.", // 分类描述
"TermsOfService": "", // 协议信息
"Contact": { // 联系方式
"Name": "Monk", // 联系人
"Email": "monksoul@outlook.com", // 联系人电子邮件
"Url": "" // 联系人个人主页
},
"License": { // 许可证
"Name": "", // 许可证名称
"Url": "" // 许可证Url
}
}
}
}

生成文档注释
using Hoa.Application.Authorization.Dtos;
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
// 设置分组名称,建议使用常量配置起来
[HoaServiceWebApiExplorer("AuthServer")]
[HoaServiceController]
public class AuthorizationAppService : IAuthorizationAppService, IAppServiceDependency
{
/// <summary>
/// 登录操作
/// </summary>
/// <param name="input">登录参数</param>
/// <returns>登录信息</returns>
public SignInOutput SignIn(SignInInput input)
{
// TODO
}
}
}

生成参数验证
Hoa Framework 内置的 Swagger 支持 ASP.NET Core 默认的 模型验证 方式和强大的 FluentValidation 两种模式。详细的 模型验证 将在第 十一、模型验证 章节说明。
🏴 配置模型验证
using FluentValidation;
using System.ComponentModel.DataAnnotations;
namespace Hoa.Application.Authorization.Dtos
{
public class SignInInput
{
[Required] // 必填
[EmailAddress] // 邮件地址
public string Email { get; set; }
[Required] // 必填
[MinLength(5)] // 最小长度
public string Password { get; set; }
[Required] // 必填
public UserType UserType { get; set; }
}
// FluentValidation 方式
public class SignInInputValidator : AbstractValidator<SignInInput>
{
public SignInInputValidator()
{
RuleFor(x => x.Email).Length(20, 250).WithMessage("长度在 20-250之间。");
}
}
}

生成多套分类文档
在 Hoa Framework 中,集成了非常强大的多分类文档生成器,只需要在类或方法上贴 [[HoaServiceWebApiExplorer(分组名称, 分组名, ...)]
即可,支持同一个接口生成多分组共享功能。该特性能够让我们的 RESTFul API 具有更具清晰的归类,是多系统统一API不二之选! 🤙 😍
🏴 生成或合并到新的分组,支持类和方法
using Hoa.Application.Authorization.Dtos;
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceWebApiExplorer("AuthServer")]
[HoaServiceController]
public class AuthorizationAppService : IAuthorizationAppService, IAppServiceDependency
{
public AuthorizationAppService()
{
}
[HoaServiceWebApiExplorer("AuthServer")]
public SignInOutput SignIn(SignInInput input)
{
// TODO
}
// 会覆盖父类,而且会出现在 "Default" 分类中
[HoaServiceWebApiExplorer("Default")]
public SignInOutput DefaultSignIn(SignInInput input)
{
// TODO
}
}
}

🏴 分组之间共享接口文档
using Hoa.Application.Authorization.Dtos;
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceWebApiExplorer("AuthServer")]
[HoaServiceController]
public class AuthorizationAppService : IAuthorizationAppService, IAppServiceDependency
{
public AuthorizationAppService()
{
}
[HoaServiceWebApiExplorer("AuthServer")]
public SignInOutput SignIn(SignInInput input)
{
// TODO
}
// 会出现在 "Default" 和 "AuthServer" 两个分类中,实现共享
[HoaServiceWebApiExplorer("Default","AuthServer")]
public SignInOutput DefaultSignIn(SignInInput input)
{
// TODO
}
}
}

生成同一个方法多个版本
using Hoa.Application.Authorization.Dtos;
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceWebApiExplorer("AuthServer")]
[HoaServiceController]
public class AuthorizationAppService : IAuthorizationAppService, IAppServiceDependency
{
public AuthorizationAppService()
{
}
public SignInOutput SignIn(SignInInput input)
{
// TODO
}
[HoaExportVersion("v2")]
public SignInOutput SignIn_v2(SignInInput input)
{
// TODO
}
}
}

支持多个请求方法访问同一个接口
[AcceptVerbs("GET")]
[AcceptVerbs("POST")]
强大的性能分析,SQL打印、异常输出
性能分析是 Hoa Framework 中 Swagger 文档一大特色,能够让我们看到实时的性能情况以及执行的数据库操作语句。是开发高质量的应用程序必备功能!
🏴 性能监控

🏴 SQL打印

支持EF Core、ADO.NET、存储过程、函数等所有数据操作监听!
🏴 异常打印

默认授权/JWT授权/策略授权/自定义授权
保护接口合理访问是我们必备的功能,Hoa Framework 内置了极其强大且非常易用的授权机制,只需要简单贴特性即可完整复杂的授权操作,包括角色授权、JWT授权、等任何自定义授权。
ASP.NET Core 自带授权方式
using Hoa.Application.Authorization.Dtos;
using Hoa.Dependencies;
using Hoa.ServiceController.Attributes;
using System;
namespace Hoa.Application.Authorization
{
[HoaServiceWebApiExplorer("AuthServer")]
[HoaServiceController]
public class AuthorizationAppService : IAuthorizationAppService, IAppServiceDependency
{
public AuthorizationAppService()
{
}
// 可匿名访问
[AllowAnonymous]
public SignInOutput SignIn(SignInInput input)
{
// TODO
}
// 必须授权才能访问
[Authorize]
public UserInfo GetUserInfo([Required] int userId)
{
// TODO
}
// 非常强大的多系统授权方式,支持多系统授权
[HoaMultipleClassifyAuthorize("A系统密钥","B系统密钥",...)]
public UserInfo GetUserInfo([Required] int userId)
{
// TODO
}
}
}

更多授权知识可查看 十二、安全授权 章节。
支持在线测试,无需 PostMan 了

最后更新于
这有帮助吗?