Use web API conventions

By Pranav Krishnamoorthy and Scott Addie

ASP.NET Core 2.2 and later includes a way to extract common API documentation and apply it to multiple actions, controllers, or all controllers within an assembly. Web API conventions are a substitute for decorating individual actions with [ProducesResponseType].

A convention allows you to:

  • Define the most common return types and status codes returned from a specific type of action.
  • Identify actions that deviate from the defined standard.

ASP.NET Core MVC 2.2 and later includes a set of default conventions in Microsoft.AspNetCore.Mvc.DefaultApiConventions. The conventions are based on the controller (ValuesController.cs) provided in the ASP.NET Core API project template. If your actions follow the patterns in the template, you should be successful using the default conventions. If the default conventions don't meet your needs, see Create web API conventions.

At runtime, Microsoft.AspNetCore.Mvc.ApiExplorer understands conventions. ApiExplorer is MVC's abstraction to communicate with OpenAPI (also known as Swagger) document generators. Attributes from the applied convention are associated with an action and are included in the action's OpenAPI documentation. API analyzers also understand conventions. If your action is unconventional (for example, it returns a status code that isn't documented by the applied convention), a warning encourages you to document the status code.

View or download sample code (how to download)

Apply web API conventions

Conventions don't compose; each action may be associated with exactly one convention. More specific conventions take precedence over less specific conventions. The selection is non-deterministic when two or more conventions of the same priority apply to an action. The following options exist to apply a convention to an action, from the most specific to the least specific:

  1. Microsoft.AspNetCore.Mvc.ApiConventionMethodAttribute — Applies to individual actions and specifies the convention type and the convention method that applies.

    In the following example, the default convention type's Microsoft.AspNetCore.Mvc.DefaultApiConventions.Put convention method is applied to the 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();
    }
    

    The Microsoft.AspNetCore.Mvc.DefaultApiConventions.Put convention method applies the following attributes to the action:

    [ProducesDefaultResponseType]
    [ProducesResponseType(StatusCodes.Status204NoContent)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    [ProducesResponseType(StatusCodes.Status400BadRequest)]
    

For more information on [ProducesDefaultResponseType], see Default Response.

  1. Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute applied to a controller — Applies the specified convention type to all actions on the controller. A convention method is decorated with hints that determine the actions to which the convention method applies. For more information on hints, see Create web API conventions).

    In the following example, the default set of conventions is applied to all actions in ContactsConventionController:

    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]
    [Route("api/[controller]")]
    public class ContactsConventionController : ControllerBase
    {
    
  2. Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute applied to an assembly — Applies the specified convention type to all controllers in the current assembly. As a recommendation, apply assembly-level attributes in the Startup.cs file.

    In the following example, the default set of conventions is applied to all controllers in the assembly:

    [assembly: ApiConventionType(typeof(DefaultApiConventions))]
    namespace ApiConventions
    {
        public class Startup
        {
    

Create web API conventions

If the default API conventions don't meet your needs, create your own conventions. A convention is:

Response types

These methods are annotated with [ProducesResponseType] or [ProducesDefaultResponseType] attributes. For example:

public static class MyAppConventions
{
    [ProducesResponseType(StatusCodes.Status200OK)]
    [ProducesResponseType(StatusCodes.Status404NotFound)]
    public static void Find(int id)
    {
    }
}

If more specific metadata attributes are absent, applying this convention to an assembly enforces that:

  • The convention method applies to any action named Find.
  • A parameter named id is present on the Find action.

Naming requirements

The [ApiConventionNameMatch] and [ApiConventionTypeMatch] attributes can be applied to the convention method that determines the actions to which they apply. For example:

[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
[ApiConventionNameMatch(ApiConventionNameMatchBehavior.Prefix)]
public static void Find(
    [ApiConventionNameMatch(ApiConventionNameMatchBehavior.Suffix)]
    int id)
{ }

In the preceding example:

  • The Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix option applied to the method indicates that the convention matches any action prefixed with "Find". Examples of matching actions include Find, FindPet, and FindById.
  • The Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix applied to the parameter indicates that the convention matches methods with exactly one parameter ending in the suffix identifier. Examples include parameters such as id or petId. ApiConventionTypeMatch can be similarly applied to types to constrain the parameter type. A params[] argument indicates remaining parameters that don't need to be explicitly matched.

Additional resources