Bien démarrer avec NSwag et ASP.NET Core

Par Christoph Nienaber, Rico Suter et Dave Brock

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

NSwag offre les avantages suivants :

  • La possibilité d’utiliser l’interface utilisateur de Swagger et le générateur Swagger.
  • Fonctionnalités de génération de code flexibles.

Avec NSwag, vous n’avez pas besoin d’une API existante, vous pouvez utiliser des API de tiers qui intègrent Swagger et génèrent une implémentation du client. NSwag vous permet d’accélérer le cycle de développement et de vous adapter facilement aux modifications de l’API.

Installation de package

Installez NSwag sur :

  • Générer la spécification Swagger pour l’API web implémentée.
  • Utiliser l’interface utilisateur Swagger pour parcourir et tester l’API web.
  • Servez le Redoc pour ajouter la documentation de l’API pour l’API web.

Pour utiliser le middleware NSwag avec ASP.NET Core, installez le package NuGet NSwag.AspNetCore. Ce package contient le middleware nécessaire pour générer et utiliser la spécification Swagger, l’interface utilisateur Swagger (v2 et v3) et l’IU ReDoc.

Vous pouvez installer le package NuGet NSwag avec l’une des méthodes suivantes :

  • À partir de la fenêtre Console du Gestionnaire de package :

    • Accédez à Affichage>Autres fenêtres>Console du Gestionnaire de package.

    • Accédez au répertoire où se trouve le fichier NSwagSample.csproj.

    • Exécutez la commande suivante :

      Install-Package NSwag.AspNetCore
      
  • À partir de la boîte de dialogue Gérer les packages NuGet :

    • Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions>Gérer les packages NuGet.
    • Affectez la valeur « nuget.org » à Source du package.
    • Entrez « NSwag.AspNetCore » dans la zone de recherche.
    • Sélectionnez le package « NSwag.AspNetCore » sous l’onglet Parcourir et cliquez sur Installer.

Ajouter et configurer l’intergiciel (middleware) Swagger

Ajoutez et configurez Swagger dans votre application ASP.NET Core en exécutant les étapes suivantes :

  • Ajoutez le générateur OpenApi à la collection de services dans Program.cs :
var builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();
builder.Services.AddOpenApiDocument();
  • Activez l’intergiciel pour traiter la spécification OpenApi générée, l’interface utilisateur Swagger et l’interface utilisateur Redoc, également dans Program.cs :
if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi();
}
  • Lancez l’application. Accédez à :
    • http://localhost:<port>/swagger pour voir l’IU de Swagger.
    • http://localhost:<port>/swagger/v1/swagger.json pour voir la spécification Swagger.

Génération de code

Vous pouvez tirer parti des fonctionnalités de génération de code de NSwag en choisissant l’une des options suivantes :

Générer du code avec NSwagStudio

  • Installez NSwagStudio en suivant les instructions fournies dans le référentiel GitHub de NSwagStudio. Sur la page de publication NSwag, vous pouvez télécharger une version xcopy qui peut être démarrée sans privilèges d’installation et d’administrateur.
  • Lancez NSwagStudio et entrez l’URL du fichier swagger.json dans la zone de texte Swagger Specification URL (URL de spécification Swagger). Par exemple, http://localhost:5232/swagger/v1/swagger.json.
  • Cliquez sur le bouton Créer une copie locale pour générer une représentation JSON de votre spécification Swagger.

NSwag Studio imports the specification and exports a CSharp Client.

  • Dans la zone Sorties, cliquez sur la case Client CSharp. Selon votre projet, vous pouvez également choisir TypeScript Client ou CSharp Web API Controller. Si vous sélectionnez CSharp Web API Controller, une spécification de service reconstruit le service, agissant comme une génération inverse.
  • Cliquez sur Générer des sorties pour produire une implémentation client C# complète du projet TodoApi.NSwag. Pour afficher le code client généré, cliquez sur l’onglet CSharp Client :
namespace MyNamespace
{
    using System = global::System;

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "14.0.1.0 (NJsonSchema v11.0.0.0 (Newtonsoft.Json v13.0.0.0))")]
    public partial class TodoClient
    {
    #pragma warning disable 8618 // Set by constructor via BaseUrl property
        private string _baseUrl;
    #pragma warning restore 8618 // Set by constructor via BaseUrl property
        private System.Net.Http.HttpClient _httpClient;
        private static System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(CreateSerializerSettings, true);

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            BaseUrl = "http://localhost:5232";
            _httpClient = httpClient;
        }

        private static Newtonsoft.Json.JsonSerializerSettings CreateSerializerSettings()
        {
            var settings = new Newtonsoft.Json.JsonSerializerSettings();
            UpdateJsonSerializerSettings(settings);
            return settings;
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set
            {
                _baseUrl = value;
                if (!string.IsNullOrEmpty(_baseUrl) && !_baseUrl.EndsWith("/"))
                    _baseUrl += '/';
            }
        }
        // code omitted for brevity

Conseil

Le code client C# est généré en fonction des sélections dans l’onglet Paramètres. Modifiez les paramètres pour effectuer des tâches telles que le renommage de l’espace de noms par défaut et la génération de méthode synchrone.

  • Copiez le code C# généré dans un fichier dans le projet client qui utilisera l’API.
  • Démarrez l’utilisation de l’API web :
var todoClient = new TodoClient(new HttpClient());

// Gets all to-dos from the API
var allTodos = await todoClient.GetAsync();

// Create a new TodoItem, and save it via the API.
await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

Personnaliser la documentation sur l’API

OpenApi fournit des options pour documenter le modèle objet afin de faciliter la consommation de l’API web.

Informations sur l’API et description

Dans Program.cs, mettez à jour AddOpenApiDocument pour configurer les informations de document de l’API web et inclure plus d’informations telles que l’auteur, la licence et la description. Importez d’abord l’espace de noms NSwag pour utiliser les classes OpenApi.

using NSwag;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApiDocument(options => {
     options.PostProcess = document =>
     {
         document.Info = new OpenApiInfo
         {
             Version = "v1",
             Title = "ToDo API",
             Description = "An ASP.NET Core Web API for managing ToDo items",
             TermsOfService = "https://example.com/terms",
             Contact = new OpenApiContact
             {
                 Name = "Example Contact",
                 Url = "https://example.com/contact"
             },
             License = new OpenApiLicense
             {
                 Name = "Example License",
                 Url = "https://example.com/license"
             }
         };
     };
});

L’IU Swagger affiche les informations de la version :

Swagger UI with version information.

commentaires XML

Pour activer les commentaires XML, procédez comme suit :

  • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Edit <project_name>.csproj.
  • Ajoutez manuellement les lignes en évidence au fichier .csproj :
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

L’activation de commentaires XML fournit des informations de débogage sur les membres et types publics non documentés. Les membres et types non documentés sont indiqués par le message d’avertissement. Par exemple, le message suivant indique une violation du code d’avertissement 1591 :

warning CS1591: Missing XML comment for publicly visible type or member 'TodoContext'

Pour supprimer des avertissements à l’échelle d’un projet, définissez une liste séparée par des points-virgules de codes d’avertissement à ignorer dans le fichier de projet. L’ajout des codes d’avertissement à $(NoWarn); applique aussi les valeurs par défaut C#.

<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Pour supprimer des avertissements uniquement pour des membres spécifiques, placez le code dans les directives de préprocesseur #pragma warning. Cette approche est utile pour le code qui ne doit pas être exposé via la documentation de l’API. Dans l’exemple suivant, le code d’avertissement CS1591 est ignoré pour l’ensemble de la classe TodoContext. La mise en œuvre de code d’avertissement est restaurée à la fin de la définition de classe. Spécifier plusieurs codes d’avertissement avec une liste délimitée par des virgules.

namespace NSwagSample.Models;

#pragma warning disable CS1591
public class TodoContext : DbContext
{
    public TodoContext(DbContextOptions<TodoContext> options) : base(options) { }

    public DbSet<TodoItem> TodoItems => Set<TodoItem>();
}
#pragma warning restore CS1591

Annotations de données

Marquez le modèle avec des attributs, qui se trouvent dans l’espace de noms System.ComponentModel.DataAnnotations, pour piloter les composants de l’interface utilisateur de Swagger.

Ajoutez l’attribut [Required] à la propriété Name de la classe TodoItem :

using System.ComponentModel;
using System.ComponentModel.DataAnnotations;

namespace NSwagSample.Models;

public class TodoItem
{
    public long Id { get; set; }

    [Required]
    public string Name { get; set; } = null!;

    [DefaultValue(false)]
    public bool IsComplete { get; set; }
}

La présence de cet attribut change le comportement de l’interface utilisateur et modifie le schéma JSON sous-jacent :

"TodoItem": {
  "type": "object",
  "additionalProperties": false,
  "required": [
    "name"
  ],
  "properties": {
    "id": {
      "type": "integer",
      "format": "int64"
    },
    "name": {
      "type": "string",
      "minLength": 1
    },
    "isComplete": {
      "type": "boolean",
      "default": false
    }
  }
}

À mesure que l’utilisation des annotations de données dans l’API web augmente, l’interface utilisateur et les pages d’aide de l’API deviennent de plus en plus descriptives et utiles.

Décrire des types de réponse

Les développeurs consommant une API web s’intéressent surtout à ce qui est retourné, en particulier les types de réponse et les codes d’erreur (s’ils ne sont pas standard). Les types de réponse et les codes d’erreur sont décrits dans les commentaires XML et les annotations de données.

L’action Create retourne un code d’état HTTP 201 en cas de réussite. Un code d’état HTTP 400 est retourné lorsque le corps de la demande publiée est null. Sans documentation appropriée dans l’interface utilisateur de Swagger, le consommateur n’a pas connaissance de ces résultats attendus. Pour résoudre ce problème, ajoutez les lignes en surbrillance de l’exemple suivant :

/// <summary>
/// Creates a TodoItem.
/// </summary>
/// <param name="item"></param>
/// <returns>A newly created TodoItem</returns>
/// <remarks>
/// Sample request:
///
///     POST /Todo
///     {
///        "id": 1,
///        "name": "Item #1",
///        "isComplete": true
///     }
///
/// </remarks>
/// <response code="201">Returns the newly created item</response>
/// <response code="400">If the item is null</response>
[HttpPost]
[ProducesResponseType(StatusCodes.Status201Created)]
[ProducesResponseType(StatusCodes.Status400BadRequest)]
public async Task<IActionResult> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    await _context.SaveChangesAsync();

    return CreatedAtAction(nameof(Get), new { id = item.Id }, item);
}

L’interface utilisateur Swagger documente désormais clairement les codes de réponse HTTP attendus (et les commentaires XML sont également affichés) :

Swagger UI showing POST Response Class description 'Returns the newly created Todo item' and '400 - If the item is null' for status code and reason under Response Messages.

Les conventions peuvent être utilisées comme alternatives à la décoration explicites des actions individuelles avec [ProducesResponseType]. Pour plus d'informations, consultez Utiliser les conventions d’API web.

Redoc

Redoc est une alternative à l’interface utilisateur Swagger. Elle est similaire, car elle fournit également une page de documentation pour l’API web à l’aide de la spécification OpenAPI. La différence est que l’interface utilisateur Redoc est plus axée sur la documentation et ne fournit pas d’interface utilisateur interactive pour tester l’API.

Pour activer Redoc, ajoutez son intergiciel à Program.cs :

if (app.Environment.IsDevelopment())
{
    // Add OpenAPI 3.0 document serving middleware
    // Available at: http://localhost:<port>/swagger/v1/swagger.json
    app.UseOpenApi();

    // Add web UIs to interact with the document
    // Available at: http://localhost:<port>/swagger
    app.UseSwaggerUi();
    
    // Add ReDoc UI to interact with the document
    // Available at: http://localhost:<port>/redoc
    app.UseReDoc(options =>
    {
        options.Path = "/redoc";
    });
}

Exécutez l’application et accédez à http://localhost:<port>/redoc pour afficher l’interface utilisateur Redoc :

Redoc documentation for the Sample API.

Par Christoph Nienaber, Rico Suter et Dave Brock

Affichez ou téléchargez l’exemple de code (procédure de téléchargement)

NSwag offre les avantages suivants :

  • La possibilité d’utiliser l’interface utilisateur de Swagger et le générateur Swagger.
  • Fonctionnalités de génération de code flexibles.

Avec NSwag, vous n’avez pas besoin d’une API existante, vous pouvez utiliser des API de tiers qui intègrent Swagger et génèrent une implémentation du client. NSwag vous permet d’accélérer le cycle de développement et de vous adapter facilement aux modifications de l’API.

Inscrire le middleware NSwag

Inscrivez le middleware NSwag pour :

  • Générer la spécification Swagger pour l’API web implémentée.
  • Utiliser l’IU Swagger pour parcourir et tester l’API web.

Pour utiliser le middleware NSwag avec ASP.NET Core, installez le package NuGet NSwag.AspNetCore. Ce package contient le middleware nécessaire pour générer et utiliser la spécification Swagger, l’interface utilisateur Swagger (v2 et v3) et l’IU ReDoc.

Vous pouvez installer le package NuGet NSwag avec l’une des méthodes suivantes :

  • À partir de la fenêtre Console du Gestionnaire de package :

    • Accédez à Affichage>Autres fenêtres>Console du Gestionnaire de package.

    • Accédez au répertoire où se trouve le fichier TodoApi.csproj.

    • Exécutez la commande suivante :

      Install-Package NSwag.AspNetCore
      
  • À partir de la boîte de dialogue Gérer les packages NuGet :

    • Cliquez avec le bouton droit sur le projet dans l’Explorateur de solutions>Gérer les packages NuGet.
    • Affectez la valeur « nuget.org » à Source du package.
    • Entrez « NSwag.AspNetCore » dans la zone de recherche.
    • Sélectionnez le package « NSwag.AspNetCore » sous l’onglet Parcourir et cliquez sur Installer.

Ajouter et configurer l’intergiciel (middleware) Swagger

Ajoutez et configurez Swagger dans votre application ASP.NET Core en exécutant les étapes suivantes :

  • Dans la méthode Startup.ConfigureServices, inscrivez les services Swagger requis :
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<TodoContext>(opt =>
        opt.UseInMemoryDatabase("TodoList"));
    services.AddMvc();

    // Register the Swagger services
    services.AddSwaggerDocument();
}
  • Dans la méthode Startup.Configure, activez l’intergiciel pour traiter la spécification Swagger générée et l’IU Swagger :
public void Configure(IApplicationBuilder app)
{
    app.UseStaticFiles();

    // Register the Swagger generator and the Swagger UI middlewares
    app.UseOpenApi();
    app.UseSwaggerUi3();

    app.UseMvc();
}
  • Lancez l’application. Accédez à :
    • http://localhost:<port>/swagger pour voir l’IU de Swagger.
    • http://localhost:<port>/swagger/v1/swagger.json pour voir la spécification Swagger.

Génération de code

Vous pouvez tirer parti des fonctionnalités de génération de code de NSwag en choisissant l’une des options suivantes :

Générer du code avec NSwagStudio

  • Installez NSwagStudio en suivant les instructions fournies dans le référentiel GitHub de NSwagStudio. Sur la page de publication NSwag, vous pouvez télécharger une version xcopy qui peut être démarrée sans privilèges d’installation et d’administrateur.

  • Lancez NSwagStudio et entrez l’URL du fichier swagger.json dans la zone de texte Swagger Specification URL (URL de spécification Swagger). Par exemple, http://localhost:44354/swagger/v1/swagger.json.

  • Cliquez sur le bouton Créer une copie locale pour générer une représentation JSON de votre spécification Swagger.

    Create local copy of Swagger specification

  • Dans la zone Sorties, cliquez sur la case Client CSharp. Selon votre projet, vous pouvez également choisir TypeScript Client ou CSharp Web API Controller. Si vous sélectionnez CSharp Web API Controller, une spécification de service reconstruit le service, agissant comme une génération inverse.

  • Cliquez sur Générer des sorties pour produire une implémentation client C# complète du projet TodoApi.NSwag. Pour afficher le code client généré, cliquez sur l’onglet CSharp Client :

//----------------------
// <auto-generated>
//     Generated using the NSwag toolchain v12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0)) (http://NSwag.org)
// </auto-generated>
//----------------------

namespace MyNamespace
{
    #pragma warning disable

    [System.CodeDom.Compiler.GeneratedCode("NSwag", "12.0.9.0 (NJsonSchema v9.13.10.0 (Newtonsoft.Json v11.0.0.0))")]
    public partial class TodoClient
    {
        private string _baseUrl = "https://localhost:44354";
        private System.Net.Http.HttpClient _httpClient;
        private System.Lazy<Newtonsoft.Json.JsonSerializerSettings> _settings;

        public TodoClient(System.Net.Http.HttpClient httpClient)
        {
            _httpClient = httpClient;
            _settings = new System.Lazy<Newtonsoft.Json.JsonSerializerSettings>(() =>
            {
                var settings = new Newtonsoft.Json.JsonSerializerSettings();
                UpdateJsonSerializerSettings(settings);
                return settings;
            });
        }

        public string BaseUrl
        {
            get { return _baseUrl; }
            set { _baseUrl = value; }
        }

        // code omitted for brevity

Conseil

Le code client C# est généré en fonction des sélections dans l’onglet Paramètres. Modifiez les paramètres pour effectuer des tâches telles que le renommage de l’espace de noms par défaut et la génération de méthode synchrone.

  • Copiez le code C# généré dans un fichier dans le projet client qui utilisera l’API.
  • Démarrez l’utilisation de l’API web :
 var todoClient = new TodoClient();

// Gets all to-dos from the API
 var allTodos = await todoClient.GetAllAsync();

 // Create a new TodoItem, and save it via the API.
var createdTodo = await todoClient.CreateAsync(new TodoItem());

// Get a single to-do by ID
var foundTodo = await todoClient.GetByIdAsync(1);

Personnaliser la documentation sur l’API

Swagger fournit des options pour documenter le modèle objet pour faciliter l’utilisation de l’API web.

Informations sur l’API et description

Dans la méthode Startup.ConfigureServices, une action de configuration passée à la méthode AddSwaggerDocument ajoute des informations comme l’auteur, la licence et la description :

services.AddSwaggerDocument(config =>
{
    config.PostProcess = document =>
    {
        document.Info.Version = "v1";
        document.Info.Title = "ToDo API";
        document.Info.Description = "A simple ASP.NET Core web API";
        document.Info.TermsOfService = "None";
        document.Info.Contact = new NSwag.OpenApiContact
        {
            Name = "Shayne Boyer",
            Email = string.Empty,
            Url = "https://twitter.com/spboyer"
        };
        document.Info.License = new NSwag.OpenApiLicense
        {
            Name = "Use under LICX",
            Url = "https://example.com/license"
        };
    };
});

L’IU Swagger affiche les informations de la version :

Swagger UI with version information

commentaires XML

Pour activer les commentaires XML, procédez comme suit :

  • Dans l’Explorateur de solutions, cliquez avec le bouton droit sur le projet, puis sélectionnez Edit <project_name>.csproj.
  • Ajoutez manuellement les lignes en évidence au fichier .csproj :
<PropertyGroup>
  <GenerateDocumentationFile>true</GenerateDocumentationFile>
  <NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>

Annotations de données

Étant donné que NSwag utilise la réflexion et que le type de retour recommandé pour les actions d’API web est ActionResult<T>, il ne peut que déduire le type de retour défini par T. Vous ne pouvez pas déduire automatiquement d’autres types de retour possibles.

Prenons l’exemple suivant :

[HttpPost]
public ActionResult<TodoItem> Create(TodoItem item)
{
    _context.TodoItems.Add(item);
    _context.SaveChanges();

    return CreatedAtRoute("GetTodo", new { id = item.Id }, item);
}

L’action précédente retourne ActionResult<T>. À l’intérieur de l’action, il retourne CreatedAtRoute. Étant donné que le contrôleur a l’attribut [ApiController], une réponse BadRequest est également possible. Pour plus d’informations, consultez Réponses HTTP 400 automatiques. Utilisez les annotations de données pour indiquer aux clients les codes d’état HTTP que cette action est susceptible de retourner. Marquez l’action avec les attributs suivants :

[ProducesResponseType(StatusCodes.Status201Created)]     // Created
[ProducesResponseType(StatusCodes.Status400BadRequest)]  // BadRequest

Dans ASP.NET Core 2.2 ou une version ultérieure, vous pouvez utiliser les conventions comme alternatives à la décoration explicite des actions individuelles avec [ProducesResponseType]. Pour plus d'informations, consultez Utiliser les conventions d’API web.

Le générateur Swagger peut maintenant décrire précisément cette action et les clients générés savent ce qu’ils reçoivent quand ils appellent le point de terminaison. Nous vous recommandons vivement de marquer toutes les actions avec ces attributs.

Pour obtenir des instructions sur les réponses HTTP que vos actions d’API doivent retourner, consultez RFC 9110 : sémantique HTTP (section 9.3). Définitions de méthode).