# 10.1、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](https://swagger.io/)

> 相信无论是前端还是后端开发，都或多或少地被接口文档折磨过。前端经常抱怨后端给的接口文档与实际情况不一致。后端又觉得编写及维护接口文档会耗费不少精力，经常来不及更新。其实无论是前端调用后端，还是后端调用后端，都期望有一个好的接口文档。但是这个接口文档对于程序员来说，就跟注释一样，经常会抱怨别人写的代码没有写注释，然而自己写起代码起来，最讨厌的，也是写注释。所以仅仅只通过强制来规范大家是不够的，随着时间推移，版本迭代，接口文档往往很容易就跟不上代码了。

发现了痛点就要去找解决方案。解决方案用的人多了，就成了标准的规范，这就是[Swagger](https://swagger.io/)的由来。

通过这套规范，你只需要按照它的规范去定义接口及接口相关的信息。再通过[Swagger](https://swagger.io/)衍生出来的一系列项目和工具，就可以做到生成各种格式的接口文档，生成多种语言的客户端和服务端的代码，以及在线接口调试页面等等。

这样，如果按照新的开发模式，在开发新版本或者迭代版本的时候，只需要更新Swagger描述文件，就可以自动生成接口文档和客户端服务端代码，做到调用端代码、服务端代码以及接口文档的一致性。

所以，[**Swagger**](https://swagger.io/) **是一个规范和完整的框架，用于生成、描述、调用和可视化 RESTful 风格的 Web 服务**。

总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法、参数和模型紧密集成到服务器端的代码，允许 API 来始终保持同步。[Swagger](https://swagger.io/) 让部署管理和使用功能强大的 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` 目录中定义即可，如：

```csharp
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 方式[可查看官方文档](https://docs.microsoft.com/zh-cn/aspnet/core/web-api/?view=aspnetcore-3.1)。

### [动态控制器服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu) 方式（推荐）

[动态控制器服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu)是 Hoa Framework 一项非常强大的功能，大大提升了我们开发的速度和避免了很多配置WebAPI 的常见低级错误。既兼容了 **ASP.NET Core 内置的 Web API模式** 而且支持Swagger文档生成、多应用权限、文档分类等强大的功能，页提供了非常强大的拦截器操作。**是目前构建 WebAPI首选方式**。

关于 [动态控制器服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu) 介绍可查看 章节：[七、控制器和服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu)。

#### :flag\_black: 示例一，将 [普通服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#pu-tong-fu-wu) 变为 [动态控制器服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu)

只需要在 [普通服务](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#pu-tong-fu-wu) 类声明地方贴 `[HoaServiceController]` 特性，并继承 `IAppServiceDependency` 即可。

**默认情况下，**[**动态控制器服务**](https://monksoul.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu) **会将 所有公开的实例方法生成对应的控制器Action，**&#x4F46;不会对私有方法和静态方法做生成操作。

```csharp
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
    }
}
```

#### :flag\_black: 示例二，手动配置实例方法不生成对应的控制器Action

只需要在方法申明顶部贴 `[HoaNonServiceWebApi]` 或 `[HoaServiceWebApiExplorer(false)]` 即可，如：

```csharp
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)]`，则这个类的所有方法包含自身都不会生成对应的控制器实例。**

#### :flag\_black: **示例三，配置Http Method生成特定请求的控制器Action**&#x20;

```csharp
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]`        |

#### :flag\_black: 示例四，设置方法已过时

```csharp
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
        }
    }
}
```

#### :flag\_black: 示例五，配置URL路由地址

```csharp
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/{区域}/{类名}/{方法名}/{值类型参数}`**

详细大家看到这里的时候已经很清楚了，[动态控制器服务](https://snrc.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu) 实际和 `ControllerBase` 的实现方式非常类似，没错，[动态控制器服务](https://snrc.gitbook.io/hoa/kongzhiqihefuwu#dong-tai-kong-zhi-qi-fu-wu) 就是将我们的 [普通服务](https://snrc.gitbook.io/hoa/kongzhiqihefuwu#pu-tong-fu-wu) 变成了 `ApiController`，此时共享 `ControllerBase` 支持的所有功能和特性。

## [Swagger](https://swagger.io/) 功能配置

通过上面第二小节 [什么是 Swagger ](https://snrc.gitbook.io/hoa/kaifangjiekouzhinan#shen-me-shi-swagger)我们已经了解了 [Swagger](https://swagger.io/) 的用处，在 Hoa Framework 框架中，除了 [Swagger](https://swagger.io/) 自带的功能之外，还拓展了很多非常方便而且具有特殊的功能，比如 **数据验证、多系统应用授权、多文档分组、性能分析**等等。

在 Hoa Framework 中，默认已经启用了 [Swagger](https://swagger.io/) 功能的支持，也就是无需手动配置。再者，我们只需要简单的贴特性的方式就可以生成非常丰富的 RESTFul 风格的文档了！

### 文档默认地址

Swagger 默认的文档链接地址是在域名的根目录下，如：`https://你的主机/` 。

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7uolAiCEzj-pnmCBw5%2F-M7urCmwlI2dJtUOQnCa%2FSnipaste_2020-05-22_13-30-35.png?alt=media\&token=41912cbf-6c21-4b4b-b7f4-7753afb18f7e)

### 设置文档信息

设置文档信息只需要修改 `appsetting.json` `HoaSwaggerOptions` 节点即可，如果文档有多个分类，只需要在当前节点的 `Groups` 节点中添加多个分类信息即可。如：

```javascript
"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
        }  
      }
    }
  }
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7uolAiCEzj-pnmCBw5%2F-M7ur3Q2xWGsJVCJAArW%2FSnipaste_2020-05-22_13-29-49.png?alt=media\&token=c23910ce-57cd-4b39-b379-d5d374cbfb1b)

### 生成文档注释

```csharp
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
        }
    }
}
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7urWc4EQsJT_2XAk-w%2F-M7usF8MQFWe-JW3BwDr%2FSnipaste_2020-05-22_13-35-05.png?alt=media\&token=388c8616-99d1-418d-9ef0-78330782e67e)

### 生成参数验证

Hoa Framework 内置的 [Swagger](https://swagger.io/) 支持 ASP.NET Core 默认的 [模型验证](https://docs.microsoft.com/zh-cn/aspnet/core/mvc/models/validation?view=aspnetcore-3.1) 方式和强大的 [FluentValidation](https://fluentvalidation.net/) 两种模式。详细的 模型验证 将在第 [十一、模型验证](https://monksoul.gitbook.io/hoa/shujujiaoyan) 章节说明。

#### :flag\_black: 配置模型验证

```csharp
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之间。");
        }
    }
}
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7utBeAGjek7Lh7O_cG%2F-M7uu1TNAHzOebvjlpPv%2FSnipaste_2020-05-22_13-42-56.png?alt=media\&token=342aeed2-f73a-4aaf-a67c-06503549683b)

### 生成多套分类文档

在 Hoa Framework 中，集成了非常强大的多分类文档生成器，只需要在**类或方法**上贴 `[[HoaServiceWebApiExplorer(分组名称, 分组名, ...)]` 即可，**支持同一个接口生成多分组共享功能**。该特性能够让我们的 RESTFul API 具有更具清晰的归类，是多系统统一API不二之选！ :call\_me: :heart\_eyes:&#x20;

#### :flag\_black: 生成或合并到新的分组，支持类和方法

```csharp
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
        }
    }
}
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7v9fs_PZlY9ZGqYsIs%2F-M7vAMQitMGZ9YLliEpJ%2FSnipaste_2020-05-22_14-58-38.png?alt=media\&token=d08bea26-7f84-4b07-a4e4-3d11aa81956c)

#### :flag\_black: 分组之间共享接口文档

```csharp
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
        }
    }
}
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7v9fs_PZlY9ZGqYsIs%2F-M7vB85IF1ED01OQJ9-O%2FSnipaste_2020-05-22_15-02-06.png?alt=media\&token=68207984-0106-43aa-a66e-1d855c608069)

### 生成同一个方法多个版本

```
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
        }
    }
}
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-MA_sXykLZ58Up1Xsui5%2F-MA_tfq7n6MdlbRZCmzo%2Fcs.png?alt=media\&token=eeaf8de1-3e28-4947-9b5d-d8fe93f92d03)

### 支持多个请求方法访问同一个接口

```csharp
[AcceptVerbs("GET")]
[AcceptVerbs("POST")]
```

### 强大的性能分析，SQL打印、异常输出

性能分析是 Hoa Framework 中 Swagger 文档一大特色，能够让我们看到实时的性能情况以及执行的数据库操作语句。是开发高质量的应用程序必备功能！

#### :flag\_black: 性能监控

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7vBNBnMcgv-4THjDrH%2F-M7vC7BgDCGYjSCOpJ2N%2FSnipaste_2020-05-22_15-06-12.png?alt=media\&token=ca0f3d8b-a0fa-4051-93f7-37e2444281ac)

#### :flag\_black: SQL打印

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7vBNBnMcgv-4THjDrH%2F-M7vCf2RmYRP1-Jx7sGK%2FSnipaste_2020-05-22_15-06-57.png?alt=media\&token=ab269e05-3e2e-45fd-9496-a30856e13e1c)

支持EF Core、ADO.NET、存储过程、函数等所有数据操作监听！

#### :flag\_black: 异常打印

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7vBNBnMcgv-4THjDrH%2F-M7vD62ItfCUq6UDVy5U%2FSnipaste_2020-05-22_15-10-36.png?alt=media\&token=4b906afa-4276-4ae9-a374-7fab08726a9d)

### 默认授权/JWT授权/策略授权/自定义授权

保护接口合理访问是我们必备的功能，Hoa Framework 内置了极其强大且非常易用的授权机制，只需要简单贴特性即可完整复杂的授权操作，包括角色授权、JWT授权、等任何自定义授权。

ASP.NET Core 自带授权方式

```csharp
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
        }
    }
}
```

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7vBNBnMcgv-4THjDrH%2F-M7vEnvb10rx8M_2OEaC%2FSnipaste_2020-05-22_15-18-08.png?alt=media\&token=b7ae9ad2-4046-4b2a-a5e4-ca4a9366e06c)

更多授权知识可查看 [十二、安全授权](https://monksoul.gitbook.io/hoa/anquanshouquan) 章节。

### 支持在线测试，无需 PostMan 了

![](https://3801536837-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M7kU_Hr8e2bVvygGB-6%2F-M7vFd5JZAKw2evbmU4s%2F-M7vFuFWYu5xJ76Zvjez%2FSnipaste_2020-05-22_15-22-59.png?alt=media\&token=125f842a-1a1c-4bf8-b340-21925921d80a)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://monksoul.gitbook.io/hoa/kaifangjiekouzhinan/10.1restful-he-swagger.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
