【译】使用Web API约定
原文链接:传送门。
ASP.NET Core 2.2及后续版本包含了一种方式来提取通用的API 文档,并将其应用在多个控制器,Action方法或者一个程序集内的所有控制器上。Web API约定可以算作用 [ProducesResponseType]装饰各个Action的一种替代方案。
一个Web API 约定允许你:
- 定义最常用的返回类型以及从一个特定类型的Action返回的状态码
- 识别偏离了预定义标准的Action
ASP.NET Core MVC 2.2及后续版本在Microsoft.AspNetCore.Mvc.DefaultApiConventions 中 包含一组默认的约定。这些约定基于 ASP.NET Core API 项目模板提供的控制器( ASP.NET Core API .cs)。如果你的Action遵循项目模板中的模式,你便成功的应用了默认约定。如果默认的约定没有满足你的需求,请参考Create web API conventions。
在运行时,Microsoft.AspNetCore.Mvc.ApiExplorer 可以理解约定。ApiExplorer是MVC的抽象,其用来与OpenAPI(也被称为Swagger)文档生成器来进行沟通。
已应用的约定的属性会与一个Action联系起来并包含在Action的OpenAPI文档中。API分析器也能够理解约定。如果你的Action没有遵循约定(比如,它返回了一个没有被应用的约定进行文档化的状态码),一个警告会鼓励你对状态码进行文档化。
应用Web API约定
约定不会进行组合。每个Action都会与一个约定进行联系。更加具体的约定优先于不太具体的约定。当多个相同优先级的约定应用于一个Action时,其选择是不确定的。
给一个Action应用约定时,有如下几种选项(按特定性由高到底):
- Microsoft.AspNetCore.Mvc.ApiConventionMethodAttribute--应用到各个Action方法中并指定约定的类型及其应用的方法。在如下的示例中,默认约定类型的Microsoft.AspNetCore.Mvc.DefaultApiConventions.Put 约定方法被应用到Update Action上。
// PUT api/contactsconvention/{guid} [HttpPut("{id}")] [ApiConventionMethod(typeof(DefaultApiConventions), nameof(DefaultApiConventions.Put))] public IActionResult Update(string id, Contact contact) { var contactToUpdate = _contacts.Get(id); if (contactToUpdate == null) { return NotFound(); } _contacts.Update(contact); return NoContent(); }
Microsoft.AspNetCore.Mvc.DefaultApiConventions.Put 约定方法会将如下属性应用到Action上。
[ProducesDefaultResponseType] [ProducesResponseType(StatusCodes.Status204NoContent)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ProducesResponseType(StatusCodes.Status400BadRequest)]
关于[ProducesDefaultResponseType]的更多信息,请参考 Default Response。
- Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute应用到控制器上--将指定的约定类型应用到控制器的所有Action上。约定方法用提示标记,这些提示确定约定方法适用的操作,更多信息,请参考Create web API conventions。在如下的示例中,默认的约定集合被应用到ContactsConventionController的 所有Action中。
[ApiController] [ApiConventionType(typeof(DefaultApiConventions))] [Route("api/[controller]")] public class ContactsConventionController : ControllerBase {
- Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute,应用到一个程序集--将指定的约定类型应用到当前程序集的所有控制器中。作为一个建议,在Startup.cs 文件中应用程序集级别的属性。在如下的示例中,默认的约定集合被应用到程序集的所有控制器中。
[assembly: ApiConventionType(typeof(DefaultApiConventions))] namespace ApiConventions { public class Startup {
创建Web API约定
如果默认的Web API约定不能满足你的需求,请创建你自己的约定。一个约定是:
- 带有方法的静态类型
- 能够在Action上定义 response types 和naming requirements。
响应类型
这些方法用[ProducesResponseType]
或者[ProducesDefaultResponseType]属性标记,举个例子:
public static class MyAppConventions { [ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] public static void Find(int id) { } }
如果出现更多的特定的元数据属性,将约定应用到程序集来保证:
- 约定方法应用到任何名为Find的Action
- 名为id的参数出现在Action中
命名需求
[ApiConventionNameMatch]
和 [ApiConventionTypeMatch]可以应用到一个约定方法上,其决定了将要应用的Action。举个例子:
[ProducesResponseType(StatusCodes.Status200OK)] [ProducesResponseType(StatusCodes.Status404NotFound)] [ApiConventionNameMatch(ApiConventionNameMatchBehavior.Prefix)] public static void Find( [ApiConventionNameMatch(ApiConventionNameMatchBehavior.Suffix)] int id) { }
在如上的示例中:
- 应用到方法的The
Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix选项表明此约定会匹配前缀为“Find”的任何Action。匹配到的Action示例包含:
Find
,FindPet
, andFindById。
- 应用到参数的Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix表明此约定将匹配只有一个参数的方法,并且这个参数一后缀标识结束。此示例包含了形如
id
或petId
.这样的参数。ApiConventionTypeMatch
可以被简单的应用到一个类型来约束参数类型。一个params[]参数表明剩余的参数没有必要显式匹配。
额外资源