Usare le convenzioni dell'API Web

La documentazione dell'API comune può essere estratta e applicata a più azioni, controller o tutti i controller all'interno di un assembly. Le convenzioni dell'API Web sono un sostituto per la decorazione di singole azioni con [ProducesResponseType].

Una convenzione consente di:

  • Definire i tipi restituiti più comuni e i codici di stato restituiti da un tipo di azione specifico.
  • Identificare le azioni che deviano dallo standard definito.

Le convenzioni predefinite sono disponibili da Microsoft.AspNetCore.Mvc.DefaultApiConventions. Le convenzioni vengono illustrate con l'aggiunta ValuesController.cs a un modello di progetto API :

using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;

namespace WebApp1.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class ValuesController : ControllerBase
    {
        // GET api/values
        [HttpGet]
        public ActionResult<IEnumerable<string>> Get()
        {
            return new string[] { "value1", "value2" };
        }

        // GET api/values/5
        [HttpGet("{id}")]
        public ActionResult<string> Get(int id)
        {
            return "value";
        }

        // POST api/values
        [HttpPost]
        public void Post([FromBody] string value)
        {
        }

        // PUT api/values/5
        [HttpPut("{id}")]
        public void Put(int id, [FromBody] string value)
        {
        }

        // DELETE api/values/5
        [HttpDelete("{id}")]
        public void Delete(int id)
        {
        }
    }
}

Azioni che seguono i modelli nel ValuesController.cs lavoro con le convenzioni predefinite. Se tuttavia le convenzioni predefinite non soddisfano le proprie esigenze, vedere Creare convenzioni dell'API Web.

In fase di runtime, Microsoft.AspNetCore.Mvc.ApiExplorer riconosce le convenzioni. ApiExplorer è l'astrazione MVC per comunicare con i generatori di documenti OpenAPI (noti anche come Swagger). Gli attributi della convenzione applicata vengono associati a un'azione e sono inclusi nella documentazione OpenAPI dell'azione. Anche gli analizzatori di API supportano le convenzioni. Se l'azione non è convenzionale (ad esempio, se restituisce un codice di stato non documentato dalla convenzione applicata), un avviso richiede di documentare il codice di stato.

Visualizzare o scaricare il codice di esempio (procedura per il download)

Applicare le convenzioni dell'API Web

Le convenzioni non sono componibili; ogni azione può essere associata a una sola convenzione. Le convenzioni più specifiche hanno la precedenza su quelle meno specifiche. Quando si applicano a un'azione due o più convenzioni con la stessa priorità, la selezione è non deterministica. Per applicare una convenzione a un'azione sono disponibili le opzioni seguenti, dalla più specifica alla meno specifica:

  1. Microsoft.AspNetCore.Mvc.ApiConventionMethodAttribute — Si applica alle singole azioni e specifica il tipo di convenzione e il metodo di convenzione applicabile.

    Nell'esempio seguente, il metodo della convenzione Microsoft.AspNetCore.Mvc.DefaultApiConventions.Put del tipo di convenzione predefinito viene applicato all'azione Update:

    // 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();
    }
    

    Il metodo della convenzione Microsoft.AspNetCore.Mvc.DefaultApiConventions.Put applica i seguenti attributi all'azione:

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

    Per altre informazioni su [ProducesDefaultResponseType], vedere Default Response (Risposta predefinita).

  2. Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute applicato a un controller : applica il tipo di convenzione specificato a tutte le azioni nel controller. Un metodo di convenzione è contrassegnato con hint che determinano le azioni a cui si applica il metodo della convenzione. Per altre informazioni sugli hint, vedere Creare convenzioni dell'API Web.

    Nell'esempio seguente il set di convenzioni predefinito viene applicato a tutte le azioni in ContactsConventionController:

    [ApiController]
    [ApiConventionType(typeof(DefaultApiConventions))]
    [Route("api/[controller]")]
    public class ContactsConventionController : ControllerBase
    {
    
  3. Microsoft.AspNetCore.Mvc.ApiConventionTypeAttribute applicato a un assembly : applica il tipo di convenzione specificato a tutti i controller nell'assembly corrente. Come raccomandazione, applicare attributi a livello di assembly nel Startup.cs file.

    Nell'esempio seguente il set di convenzioni predefinito viene applicato a tutti i controller dell'assembly:

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

Creare convenzioni dell'API Web

Se le convenzioni dell'API predefinite non soddisfano le proprie esigenze, creare convenzioni personalizzate. Una convenzione è:

Tipi di risposta

Questi metodi vengono annotati con attributi [ProducesResponseType] o [ProducesDefaultResponseType]. Ad esempio:

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

Se non sono presenti attributi dei metadati più specifici, l'applicazione di questa convenzione a un assembly impone quanto segue:

  • Il metodo della convenzione viene applicato a qualsiasi azione con nome Find.
  • Un parametro con nome id è presente nell'azione Find.

Requisiti per la denominazione

Gli attributi [ApiConventionNameMatch] e [ApiConventionTypeMatch] possono essere applicati al metodo convenzione che determina le azioni nelle quali vengono implementati. Ad esempio:

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

Nell'esempio precedente:

  • L'opzione Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Prefix applicata al metodo indica che la convenzione corrisponde a qualsiasi azione con il prefisso "Find". Find, FindPet e FindById sono esempi di azioni corrispondenti.
  • Microsoft.AspNetCore.Mvc.ApiExplorer.ApiConventionNameMatchBehavior.Suffix applicato al parametro indica che la convenzione corrisponde a metodi che hanno esattamente un parametro che termina con l'identificatore del suffisso. Sono esempi parametri come id o petId. ApiConventionTypeMatch può essere applicato in modo analogo ai tipi, per vincolare il tipo del parametro. Un argomento params[] indica i parametri rimanenti, per i quali non è necessario che sia rilevata una corrispondenza esplicita.

Risorse aggiuntive