钱行慕

导航

【译】使用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应用约定时,有如下几种选项(按特定性由高到底):

  1. 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

  2. Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute应用到控制器上--将指定的约定类型应用到控制器的所有Action上。约定方法用提示标记,这些提示确定约定方法适用的操作,更多信息,请参考Create web API conventions。在如下的示例中,默认的约定集合被应用到ContactsConventionController的 所有Action中。
    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]
    [Route("api/[controller]")]
    public class ContactsConventionController : ControllerBase
    {
  3. Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute,应用到一个程序集--将指定的约定类型应用到当前程序集的所有控制器中。作为一个建议,在Startup.cs 文件中应用程序集级别的属性。在如下的示例中,默认的约定集合被应用到程序集的所有控制器中。
    [assembly: ApiConventionType(typeof(DefaultApiConventions))]
    namespace ApiConventions
    {
        public class Startup
        {

     

创建Web API约定

如果默认的Web API约定不能满足你的需求,请创建你自己的约定。一个约定是:

响应类型

这些方法用[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示例包含:FindFindPet, and FindById。
  • 应用到参数的Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix表明此约定将匹配只有一个参数的方法,并且这个参数一后缀标识结束。此示例包含了形如 id 或 petId.这样的参数。ApiConventionTypeMatch 可以被简单的应用到一个类型来约束参数类型。一个params[]参数表明剩余的参数没有必要显式匹配。

额外资源

posted on 2020-11-18 13:52  钱行慕  阅读(374)  评论(0编辑  收藏  举报