AVIS IMPORTANT Si vous améliorez les grandes versions! |
---|
* Si vous passez de 4.x à 5.x, il y a plusieurs changements de rupture à connaître. Voir les notes de publication pour plus de détails * Si vous faites le saut de 3.x à 4.x d'abord, il y a aussi des dragons là-bas. Voir ces notes de sortie ici |
Outillage de fanfaronnade pour API construit avec ASP.NET Core. Générez une belle documentation API, y compris une interface utilisateur pour explorer et tester les opérations, directement à partir de vos itinéraires, contrôleurs et modèles.
En plus de son générateur Swagger 2.0 et OpenAPI 3.0, Swashbuckle fournit également une version intégrée du génial Swagger-UI qui est alimenté par le swagger json généré. Cela signifie que vous pouvez compléter votre API avec une documentation de vie qui est toujours en phase avec le dernier code. Mieux encore, cela nécessite un codage et une maintenance minimaux, vous permettant de vous concentrer sur la construction d'une API impressionnante.
Et ce n'est pas tout ...
Une fois que vous avez une API qui peut se décrire dans Swagger, vous avez ouvert le coffre au trésor d'outils basés sur Swagger, y compris un générateur de clients qui peut être ciblé sur un large éventail de plates-formes populaires. Voir Swagger-Codegen pour plus de détails.
Version swashbuckle | ASP.NET Core | SPHAGER / OpenAPI Spec. | swagger-ui | Ui redoc |
---|---|---|---|---|
CI | > = 2.0.0 | 2.0, 3.0 | 5.xx | 2.xx |
6.9.0 | > = 2.0.0 | 2.0, 3.0 | 5.17.14 | 2.1.5 |
5.6.3 | > = 2.0.0 | 2.0, 3.0 | 3.32.5 | 2.0.0-RC.40 |
4.0.0 | > = 2.0.0, <3.0.0 | 2.0 | 3.19.5 | 1.22.2 |
3.0.0 | > = 1.0.4, <3.0.0 | 2.0 | 3.17.1 | 1.20.0 |
2.5.0 | > = 1.0.4, <3.0.0 | 2.0 | 3.16.0 | 1.20.0 |
Installez le package NUGET standard dans votre application Core ASP.NET.
Package Manager : Install-Package Swashbuckle.AspNetCore CLI : dotnet add package Swashbuckle.AspNetCore
Dans la méthode ConfigureServices
de Startup.cs
, enregistrez le générateur de fanfaronnade, en définissant un ou plusieurs documents de fanfarts.
Utilisation de Microsoft.OpenAPI.Models;
services.addmvc (); services.addswaggerGen (c => {c.swaggerdoc ("v1", new OpenAPiinfo {title = "my api", version = "v1"});});
Assurez-vous que vos actions et paramètres de l'API sont décorés avec des liaisons explicites "HTTP" et "de".
[Httppost] public void createProduct ([from body] produit produit) ...
[Httpget] public ienumerable <produit> Recherche de recherche ([FromQuery] Mots-clés de chaîne) ...
Remarque: Si vous omettez les liaisons des paramètres explicites, le générateur les décrira comme paramètres "requête" par défaut.
Dans la méthode Configure
, vous devez exposer le fanfaron généré en tant que point de terminaison JSON par l'une des méthodes suivantes:
app.mapendpoints (endpoints => {// ... endpoint.mapswagger ();});
app.useswagger ();
À ce stade, vous pouvez tourner votre application et voir le JSON Swagger généré à "/wagger/v1/swagger.json".
Insérer le middleware
Ajoutez des points de terminaison si vous utilisez le routage basé sur les points de terminaison.
Facultativement, insérez le middleware Swagger-UI si vous souhaitez exposer la documentation interactive, en spécifiant le (s) point de terminaison JSON Swagger pour l'alimenter.
app.useswaggerui (c => {c.swaggerendpoint ("v1 / swagger.json", "mon API v1");});
Vous pouvez maintenant redémarrer votre application et consulter les documents interactifs générés automatiquement à "/ Swagger".
Dans les versions antérieures à 5.0.0
, Swashbuckle générera des schémas (descriptions des types de données exposés par une API) en fonction du comportement du sérialiseur Newtonsoft . Cela avait du sens parce que c'était le sérialiseur qui a expédié avec ASP.NET Core à l'époque. Cependant, depuis la version 3.0.0
, ASP.Net Core présente un nouveau sérialiseur System.Text.json (STJ) prêt à l'emploi, et si vous souhaitez continuer à utiliser NewTonsoft , vous devez installer un package séparé et explicitement opt-in. De Swashbuckle 5.0.0
et au-delà, un modèle similaire est utilisé. Autrement dit, Swashbuckle prêt à l'emploi supposera que vous utilisez le sérialiseur STJ et que vous générez des schémas en fonction de son comportement. Si vous utilisez NewTonsoft , vous devrez installer un package Swashbuckle séparé et opter explicitement. Il s'agit d'une étape requise, quelle que soit la version du noyau ASP.NET que vous utilisez .
En résumé ...
Si vous utilisez System.Text.json (STJ) , la configuration décrite ci-dessus sera suffisante et les options / attributs STJ seront automatiquement honorés par le générateur de fanfaronnade.
Si vous utilisez NewTonsoft , vous devrez installer un package séparé et opter explicitement pour vous assurer que les paramètres / attributs de NewTonsoft sont automatiquement honorés par le générateur de fanfaronnade:
Package Manager : Install-Package Swashbuckle.AspNetCore.Newtonsoft CLI : dotnet add package Swashbuckle.AspNetCore.Newtonsoft
Services.Addmvc (); Services.AddswaggerGen (C => {C.SwaggerDoc ("V1", New OpenAPIinfo {Title = "My API", version = "V1"});}); Services.AddswaggerGenneWTonsOfTSUpport (); // Opt-in explicite - doit être placé après AddSwaggerGen ()
Swashbuckle s'appuie fortement sur ApiExplorer
, la couche de métadonnées API qui est expédiée avec ASP.NET Core. Si vous utilisez l'assistance AddMvc
pour bootstrap la pile MVC, APIExplorer sera automatiquement enregistré et SB fonctionnera sans problème. Cependant, si vous utilisez AddMvcCore
pour une pile MVC plus jumelée, vous devrez ajouter explicitement le service APIExplorer:
services.addmvccore (). addapiexplorer ();
De plus, si vous utilisez le routage conventionnel (par opposition à l'attribut de routage), tous les contrôleurs et les actions sur les contrôleurs qui utilisent le routage conventionnel ne seront pas représentés dans APIEXPLORER, ce qui signifie que Swashbuckle ne pourra pas trouver ces contrôleurs et générer un fanfaron opérations d'eux. Par exemple:
app.usemvc (routes => {// swaggergen ne trouvera pas de contrôleurs qui sont acheminés via cette technique. Routes.MapRoute ("Default", "{contrôleur = home} / {action = index} / {id?}") ;});
Vous devez utiliser le routage des attributs pour tous les contrôleurs que vous souhaitez représenter dans votre (s) document (s):
[Route ("Exemple")] classe publique ExampleController: Controller {[httpget ("")] public iActionResult Dostuff () {/ ** /}}
Reportez-vous à la documentation de routage pour plus d'informations.
Swashbuckle se compose de plusieurs composants qui peuvent être utilisés ensemble ou individuellement en fonction de vos besoins. À la base, il y a un générateur de fanfaronnade, du middleware pour l'exposer sous forme de points de terminaison JSON et une version emballée du Swagger-UI. Ces 3 packages peuvent être installés avec Swashbuckle.AspNetCore
"MetaPackage" et fonctionneront ensemble de manière transparente (voir commencer) pour fournir de beaux documents API qui sont automatiquement générés à partir de votre code.
De plus, il existe des packages complémentaires (outils CLI, une autre interface utilisateur, etc.) que vous pouvez éventuellement installer et configurer au besoin.
Emballer | Description |
---|---|
Swashbuckle.aspnetcore.swagger | Expose les points de terminaison JSON Swagger. Il s'attend à ce qu'une implémentation d' ISwaggerProvider soit enregistrée dans le conteneur DI, qu'il demande à récupérer OpenAPIDocument(s) qui sont ensuite exposés en JSON sérialisé |
Swashbuckle.aspnetcore.swaggergen | Injecte une implémentation d' ISwaggerProvider qui peut être utilisée par le composant ci-dessus. Cette implémentation particulière génère OpenApiDocument(s) à partir de vos itinéraires, contrôleurs et modèles |
Swashbuckle.aspnetcore.swaggerui | Expose une version intégrée du Swagger-UI. Vous spécifiez les points de terminaison de l'API où il peut obtenir Swagger JSON, et il les utilise pour alimenter les documents interactifs pour votre API |
Emballer | Description |
---|---|
Swashbuckle.aspnetcore.annotations | Comprend un ensemble d'attributs personnalisés qui peuvent être appliqués aux contrôleurs, actions et modèles pour enrichir le fanfaron généré |
Swashbuckle.aspnetcore.cli | Fournit une interface de ligne de commande pour récupérer Swagger directement à partir d'un assemblage de démarrage et écrire dans le fichier |
Swashbuckle.aspnetcore.redoc | Expose une version intégrée de l'interface utilisateur Redoc (une alternative à Swagger-UI) |
Ces forfaits sont fournis par la communauté open source.
Emballer | Description |
---|---|
Swashbuckle.aspnetcore.filters | Quelques filtres Swashbuckle utiles qui ajoutent de la documentation supplémentaire, par exemple la demande et les exemples de réponse, les informations d'autorisation, etc. Voir sa lecture pour plus de détails |
Unchase.swashbuckle.aspnetcore.extensions | Quelques extensions (filtres) utiles, qui ajoutent de la documentation supplémentaire, par exemple, masquer les pathitems pour les rôles inacceptés, corriger les énumérations pour la génération de code client, etc. Voir sa lecture pour plus de détails |
Microelements.swashbuckle.fluentvalidation | Utilisez des règles de survalidation Fluent au lieu de composants des attributs de modélisation pour augmenter les schémas de fanfaronnade générés |
MMLIB.SWAGGFOROCELOT | Documents agrégés sur les microservices directement sur la passerelle API Ocelot |
Les étapes décrites ci-dessus vous mettront en service avec une configuration minimale. Cependant, Swashbuckle offre beaucoup de flexibilité à personnaliser comme bon vous semble. Consultez le tableau ci-dessous pour la liste complète des options:
Swashbuckle.aspnetcore.swagger
Changer le chemin des points de terminaison JSON Swagger
Modifier le fanfaron avec le contexte de la demande
Sérialiser Swagger JSON au format 2.0
Travailler avec des répertoires virtuels et des procurations inversées
Personnalisation de la façon dont le document OpenAPI est sérialisé
Swashbuckle.aspnetcore.swaggergen
Affecter les opérations explicites
Réponses des opérations répertoriées
Flag Paramètres requis et propriétés de schéma
Gérer les formulaires et les téléchargements de fichiers
Gérer les téléchargements de fichiers
Inclure des descriptions des commentaires XML
Fournir des métadonnées API mondiales
Générer plusieurs documents de fanfaronnade
Omettre les opérations obsolètes et / ou les propriétés du schéma
Omettre les opérations arbitraires
Personnaliser les balises d'opération (par exemple pour le regroupement d'interface utilisateur)
Modifier l'ordre de tri de l'opération (par exemple pour le tri de l'interface utilisateur)
Personnaliser les identifiants de schéma
Remplacer le schéma pour des types spécifiques
Étendre le générateur avec des filtres de fonctionnement, de schéma et de documents
Ajouter des définitions et des exigences de sécurité
Ajouter des définitions et des exigences de sécurité pour Bearer Auth
Héritage et polymorphisme
Swashbuckle.aspnetcore.swaggerui
Changer le chemin relatif vers l'interface utilisateur
Modifier le titre du document
Modifier les chemins CSS ou JS
Énumérez plusieurs documents de fanfaronnade
Appliquer les paramètres Swagger-UI
Injecter JavaScript personnalisé
Injecter CSS personnalisé
Personnaliser index.html
Activer les flux OAuth2.0
Utilisez les intercepteurs de la demande et de la réponse côté client
Swashbuckle.aspnetcore.annotations
Installer et activer les annotations
Enrichir les métadonnées de l'opération
Enrichir les métadonnées de réponse
Enrichir les métadonnées des paramètres
Enrichir les métadonnées de demande
Enrichir les métadonnées du schéma
Appliquer des filtres de schéma à des types spécifiques
Ajouter des métadonnées de balise
Swashbuckle.aspnetcore.cli
Récupérer Swagger directement à partir d'un ensemble de startup
Utilisez l'outil CLI avec une configuration d'hôte personnalisée
Swashbuckle.aspnetcore.redoc
Changer le chemin relatif vers l'interface utilisateur
Modifier le titre du document
Appliquer les paramètres redoc
Injecter CSS personnalisé
Personnaliser index.html
Par défaut, Swagger JSON sera exposé sur la route suivante - "/wagger/DocumentName )/swagger.json". Si nécessaire, vous pouvez changer cela lorsque vous activez le middleware Swagger. Les routes personnalisées doivent inclure le paramètre {documentName}
.
app.useswagger (c => {c.RouteTemplate = "api-docs / {documentName} /wagger.json";})
Remarque: Si vous utilisez le middleware Swaggerui, vous devrez également mettre à jour sa configuration pour refléter les nouveaux points de terminaison:
app.useswaggerui (c => {c.swaggerendpoint ("/ api-docs / v1 / swagger.json", "mon API v1");})
Remarque: Si vous avez également besoin de mettre à jour le chemin relatif sur lequel l'interface utilisateur est disponible, vous devrez suivre les instructions trouvées dans le chemin relatif du changement vers l'interface utilisateur.
Si vous avez besoin de définir des métadonnées Swagger en fonction de la demande actuelle, vous pouvez configurer un filtre exécuté avant de sérialiser le document.
app.useswagger (c => {C.PreSerializeFilters.add ((swagger, httpreq) => {swagger.servers = new list <openapiserver> {new Openapiserver {url = $ "{httpreq.scheme}: // {httpreq. Host.value} "}};});});
L' OpenApiDocument
et le HttpRequest
actuel sont tous deux transmis au filtre. Cela offre beaucoup de flexibilité. Par exemple, vous pouvez ajouter un serveur API explicite basé sur l'en-tête "hôte" (comme indiqué), ou vous pouvez inspecter les informations de session ou un en-tête d'autorisation et supprimer les opérations du document en fonction des autorisations utilisateur.
Par défaut, Swashbuckle générera et exposera Swagger JSON dans la version 3.0 de la spécification, officiellement appelée spécification OpenAPI. Cependant, pour prendre en charge la compatibilité en arrière, vous pouvez choisir de continuer à l'exposer au format 2.0 avec l'option suivante:
app.useswagger (c => {C.SerializeSv2 = true;});
Les répertoires virtuels et les proxies inversés peuvent entraîner des problèmes d'applications qui génèrent des liens et des redirectes, en particulier si l'application renvoie les URL absolues en fonction de l'en-tête Host
et d'autres informations à partir de la demande actuelle. Pour éviter ces problèmes, Swashbuckle utilise des URL relatives dans la mesure du possible et encourage leur utilisation lors de la configuration du middleware Swaggerui et Redoc.
Par exemple, pour câbler le middleware Swaggerui, vous fournissez l'URL à un ou plusieurs documents OpenAPI / Swagger. C'est l'URL que le Swagger-UI, une application côté client, appellera pour récupérer vos métadonnées API. Pour vous assurer que cela fonctionne derrière les répertoires virtuels et les proxys inversés, vous devez exprimer cela par rapport à la RoutePrefix
du Swagger-UI lui-même:
app.useswaggerui (c => {c.routeprefix = "swagger"; c.swaggerendpoint ("v1 / swagger.json", "mon API v1");});
Remarque: Dans les versions précédentes des documents, vous avez peut-être vu cela exprimé comme un lien relatif racinaire (par exemple /swagger/v1/swagger.json
). Cela ne fonctionnera pas si votre application est hébergée sur un répertoire virtuel IIS ou derrière un proxy qui coupe le chemin de demande avant de transférer. Si vous passez à la syntaxe relative à la page illustrée ci-dessus, cela devrait fonctionner dans tous les cas.
Par défaut, Swashbuckle sérialisera le document OpenAPI à l'aide des méthodes de sérialisation de l'objet Document OpenAPI. Si une sérialisation personnalisée est souhaitée, il est possible de créer un sérialiseur de document personnalisé qui implémente l'interface ISwaggerDocumentSerializer
. Cela peut être défini sur les SwaggerOptions
dans la collection de services à l'aide ConfigureSwagger()
:
Note
Si vous prévoyez d'utiliser l'outil de ligne de commande pour générer des fichiers de spécification OpenAPI, cela doit être fait sur la collection de services à l'aide de ConfigureSwagger()
.
Services.ConfiguresWagger (Options => {Option.SetCustomDocumentSerializer <UstomDocumentSerializer> ();})
Lorsque l'outil de ligne de commande n'est pas utilisé, il peut également être fait sur l'hôte de l'application:
app.useswagger (options => {options.setCustomDocumentSerializer <ustomDocumentSerializer> ();})
Dans Swagger, les opérations peuvent se voir attribuer un operationId
. Cet identifiant doit être unique parmi toutes les opérations décrites dans l'API. Les outils et les bibliothèques (par exemple les générateurs de clients) peuvent utiliser le OperationId pour identifier de manière unique une opération, par conséquent, il est recommandé de suivre les conventions de dénomination de programmation courantes.
Générant automatiquement un ID qui correspond à ces exigences, tout en fournissant un nom qui serait significatif dans les bibliothèques de clients est une tâche non triviale et donc, Swashbuckle omet le operationId
par défaut. Cependant, si nécessaire, vous pouvez attribuer operationIds
en décorant des itinéraires individuels ou en fournissant une stratégie personnalisée.
Option 1) Décorer les routes avec une propriété Name
[Httpget ("{id}", name = "getProductById")] public iacEctionResult get (int id) // operationd = "getProductByid"
Option 2) Fournir une stratégie personnalisée
// startup.csservices.addswaggerGen (c => {... // Utiliser le nom de la méthode comme operationId C.CustomOperationID (apidesc => {return apidesc.tryGetMethodInfo (out methodinfo Methodinfo)? Methodinfo.Name: null;});} Methodinfo)? ) // ProductsController.cs [httpget ("{id}")] public iActionResult getProductById (int id) // operationd = "getProductById"
Remarque: Avec l'une ou l'autre approche, les auteurs d'API sont chargés de garantir l'unicité des operationIds
dans toutes les opérations
Par défaut, Swashbuckle générera une réponse "200" pour chaque opération. Si l'action renvoie un DTO de réponse, cela sera utilisé pour générer un schéma pour le corps de réponse. Par exemple ...
[Httppost ("{id}")] public produit getbyid (int id)
Produira les métadonnées de réponse suivantes:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } } }
Si vous devez spécifier un code d'état différent et / ou des réponses supplémentaires, ou si vos actions renvoient IActionResult
au lieu d'une réponse DTO, vous pouvez explicitement décrire des réponses avec le produit de ProducesResponseTypeAttribute
qui est expédié avec ASP.NET Core. Par exemple ...
[HTTPPOST ("{id}")] [Produit unSponSety (TypeOf (Product), 200)] [Produit unSponSetype (TypeOf (iDictionary <String, String>), 400)] [ProduceSResponSetype (500)] public IacTresult Getbyid (int id)
Produira les métadonnées de réponse suivantes:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } }, 400: { description: "Bad Request", content: { "application/json": { schema: { type: "object", additionalProperties: { type: "string" } } } } }, 500: { description: "Internal Server Error", content: {} } }
Dans un document Swagger, vous pouvez signaler les paramètres et les propriétés de schéma requises pour une demande. Si un paramètre (niveau supérieur ou basé sur une propriété) est décoré avec le BindRequiredAttribute
ou RequiredAttribute
, Swashbuckle l'a automatiquement signalé en tant que paramètre "requis" dans le fanfaron généré:
// ProductsController.cspublic IactionResult Search ([FromQuery, bindRequired] String Mots-clés, [FromQuery] PagingParams PAGINYPARAMS) {if (! ModelState.isvalid) return badRequest (ModelState); ...} // SearchParams.csvalid ClassParams {[obligatoire ] public int pageno {get; ensemble; } public int pagesize {get; ensemble; }}
En plus des paramètres, Swashbuckle honorera également le RequiredAttribute
lorsqu'il est utilisé dans un modèle lié au corps de la demande. Dans ce cas, les propriétés décorées seront signalées comme des propriétés "requises" dans le corps Description:
// ProductsController.cspublic iActionResult Create ([frombody] produit produit) {if (! ModelState.isvalid) return badRequest (ModelState); ...} // product.cspublic class Product {[requis] public String name {get; ensemble; } public String Description {get; ensemble; }}
Ce contrôleur acceptera deux valeurs de champ de formulaire et un téléchargement de fichiers nommé à partir de la même forme:
[Httppost] public void uploadfile ([Fromform] String Description, [Fromform] DateTime ClientDate, fichier iformfile)
Remarque importante: Selon les documents Core ASP.NET, vous n'êtes pas censé décorer les paramètres
IFormFile
avec l'attribut[FromForm]
car la source de liaison est automatiquement déduite du type. En fait, la valeur inférée estBindingSource.FormFile
et si vous appliquez l'attribut, il sera défini surBindingSource.Form
à la place, qui bousilleApiExplorer
, le composant de métadonnées qui est expédié avec ASP.NET Core et est fortement remis par Swashbuckle. Un problème particulier ici est que SwaggerUi ne traitera pas le paramètre comme un fichier et n'affichera donc pas de bouton de téléchargement de fichiers, si vous incluez à tort cet attribut.
ApiExplorer
(le composant de métadonnées Core ASP.NET sur lequel Swashbuckle est construit) ne fait pas surface les types FileResult
par défaut et vous devez donc le dire explicitement avec l'attribut ProducesResponseType
(ou Produces
sur .NET 5 ou plus):
[Httpget ("{nom de filen}")] [produit la réponse (typeof (filestreamResult), statuscodes.status200ok, "image / jpeg")] public filestreamresult getfile (String filename)
Pour améliorer les documents générés avec des descriptions respectueuses de l'homme, vous pouvez annoter les actions et les modèles du contrôleur avec des commentaires XML et configurer Swashbuckle pour incorporer ces commentaires dans le swagger JSON sorti:
Ouvrez la boîte de dialogue Propriétés pour votre projet, cliquez sur l'onglet "Build" et assurez-vous que "le fichier de documentation XML" est coché ou ajoutez <GenerateDocumentationFile>true</GenerateDocumentationFile>
à la section <PropertyGroup>
de votre fichier de projet .csproj. Cela produira un fichier contenant tous les commentaires XML au moment de la construction.
À ce stade, toutes les classes ou méthodes qui ne sont pas annotées avec des commentaires XML déclencheront un avertissement de construction. Pour supprimer cela, entrez le code d'avertissement "1591" dans le champ "Supprimer les avertissements" dans la boîte de dialogue Propriétés ou Ajouter <NoWarn>1591</NoWarn>
à la section <PropertyGroup>
de votre fichier de projet .csproj.
Configurez Swashbuckle pour incorporer les commentaires XML sur le fichier dans le swagger json généré:
Services.AddswaggerGen (c => {c.swaggerdoc ("v1", nouveau openapiinfo {title = "my api - v1", version = "v1"}); c.includExmlComments (assembly.getExecutingAssembly ()); // ou C. includexmlcomments (typeof (myController) .Assembly));}
Annotez vos actions avec résumé, remarques, paramètres et balises de réponse:
/// <summary> /// récupère un produit spécifique par ID unique /// </summary> /// <Remarks> Awesomeness! </ Remarks> /// <param name = "id" Exemple = "123" > L'ID du produit </ param> /// <Code de réponse = "200"> Produit récupéré </ponsect> /// <Code de réponse = "404"> Produit introuvable </ponse> /// <Code de réponse = "500"> Oups! Impossible de rechercher votre produit pour le moment </ponse> [httpget ("{id}")] [produit unSponSetype (typeof (produit), 200)] [ProduapesResponSetype (404)] [produit unSponSetype (500)] Product GetById (int identifiant)
Vous pouvez également annoter les types avec des balises de résumé et d'exemples:
Classe publique Product {/// <summary> /// Le nom du produit /// </summary> /// <nexe> Chaussures de basket-ball masculin </XILD> Nom de chaîne publique {get; ensemble; } /// <summary> /// Quantité laissée en stock /// </summary> /// <nampe> 10 </ Exampe> public int DovableStock {get; ensemble; } /// <summary> /// Les tailles que le produit est disponible en /// </summary> /// <nexe> ["Small", "Medium", "Large"] </ Exemple> Liste publique < String> tailles {get; ensemble; }}
Reconstruisez votre projet pour mettre à jour le fichier de commentaires XML et accéder au point de terminaison JSON Swagger. Notez comment les descriptions sont mappées sur les champs de fanfaronnade correspondants.
Remarque: Vous pouvez également fournir des descriptions de schéma de fanfaronnade en annotant vos modèles API et leurs propriétés avec des étiquettes de résumé. Si vous avez plusieurs fichiers de commentaires XML (par exemple, des bibliothèques distinctes pour les contrôleurs et les modèles), vous pouvez invoquer plusieurs fois la méthode IncludeExmComments et ils seront tous fusionnés dans le swagger JSON sorti.
En plus des "pathitems", "opérations" et "réponses", que Swashbuckle génère pour vous, Swagger prend également en charge les métadonnées mondiales (voir https://swagger.io/specification/#oasobject). Par exemple, vous pouvez fournir une description complète de votre API, des conditions de service ou même des informations de contact et de licence:
c.swaggerdoc ("v1", nouveau openapiinfo {title = "my api - v1", version = "v1", description = "un exemple d'API à la démonstration swashbuckle", termesfservice = new uri ("http://tempuri.org / Termes "), contacter = new OpenAPIContact {name =" Joe Developer ", Courriel =" [email protected] "}, licence = new OpenApilicence {name =" Apache 2.0 ", url = new uri (" https: //www.apache.org/licenses/license-2.0.html ")}});
CONSEIL: Utilisez Intellisense pour voir quels autres domaines sont disponibles.
Avec la configuration décrite ci-dessus, le générateur inclura toutes les opérations d'API dans un seul document Swagger. Cependant, vous pouvez créer plusieurs documents si nécessaire. Par exemple, vous voudrez peut-être un document séparé pour chaque version de votre API. Pour ce faire, commencez par définir plusieurs documents Swagger dans Startup.cs
:
Services.AddswaggerGen (c => {c.swaggerdoc ("v1", nouveau openapiinfo {title = "my api - v1", version = "v1"}); c.swaggerdoc ("v2", new OpenAPiinfo {title = " Mon API - v2 ", version =" v2 "});})
Prenez note du premier argument à Swaggerdoc. Ce doit être un nom adapté aux URI qui identifie uniquement le document. Il est par la suite utilisé pour inventer le chemin pour demander le swagger JSON correspondant. Par exemple, avec le routage par défaut, les documents ci-dessus seront disponibles sur "/wagger/v1/swagger.json" et "/wagger/v2/swagger.json".
Ensuite, vous devrez informer Swashbuckle quelles actions à inclure dans chaque document. Bien que cela puisse être personnalisé (voir ci-dessous), par défaut, le générateur utilisera la propriété ApiDescription.GroupName
, une partie de la couche de métadonnées intégrée qui est livrée avec ASP.NET Core, pour faire cette distinction. Vous pouvez le définir en décorant des actions individuelles ou en appliquant une large convention d'application.
Pour inclure une action dans un document Swagger spécifique, décorez-le avec le nom de groupe ApiExplorerSettingsAttribute
et définissez GroupName
au nom du document correspondant (sensible à la casse):
[Httppost] [apiexplorersettings (groupName = "v2")] public void post ([frombody] produit produit)
Pour regrouper par convention au lieu de décorer chaque action, vous pouvez appliquer un contrôleur personnalisé ou une convention d'action. Par exemple, vous pouvez câbler la convention suivante pour attribuer des actions à des documents en fonction de l'espace de noms du contrôleur.
// apiexplorerGroupperversionConvention.cspublic class apiexplorerGroupperversionConvention: iControllerModelConvention {public void applique (contrôleur de contrôleur de contrôle) {var ContrôneraSpace = Controller.ControllerType.Namespace; // par exemple "Controllers.v1" var apiversion = CONTRICLERNAMESPACE.Split ('. Services.Addmvc (c => C.Conventions.Add (Nouveau apiexplorerGroupperVersionConvention ())); ...}
Lors de la sélection des actions pour un document Swagger donné, le générateur invoque un DocInclusionPredicate
contre chaque ApiDescription
qui est apparue par le cadre. L'implémentation par défaut inspecte ApiDescription.GroupName
et renvoie true si la valeur est nul ou égale au nom du document demandé. Cependant, vous pouvez également fournir un prédicat d'inclusion personnalisé. Par exemple, si vous utilisez une approche basée sur des attributs pour implémenter le versioning API (par exemple Microsoft.aspnetcore.mvc.versioning), vous pouvez configurer un prédicat personnalisé qui exploite les attributs de version à la place:
c.DocinclusionPredicate ((docname, apidesc) => {if (! apidesc.tryGetMethodInfo (out méthodinfo methodinfo)) return; var versions = methodinfo.declarenType .getCustomAtTributes (true) .ofType <apirsionAttribute> (). SelectMany (attribute). > att.Versions);
Si vous utilisez le middleware SwaggerUI
, vous devrez spécifier tous les points de terminaison de fanfaron supplémentaires que vous souhaitez exposer. Voir Liste plusieurs documents de fanfaronnade pour en savoir plus.
La spécification Swagger comprend un drapeau deprecated
pour indiquer qu'une opération est obsolète et doit être absorbée d'utiliser. Le générateur de fanfaronnade définira automatiquement cet drapeau si l'action correspondante est décorée de l' ObsoleteAttribute
. Cependant, au lieu de définir un drapeau, vous pouvez configurer le générateur pour ignorer complètement les actions obsolètes:
Services.AddswaggerGen (c => {... C.IgnoreObSoleActions ();};
Une approche similaire peut également être utilisée pour omettre des propriétés obsolètes à partir de schémas dans la sortie de fanfaronnade. Autrement dit, vous pouvez décorer les propriétés du modèle avec l' ObsoleteAttribute
et configurer swashbuckle pour omettre ces propriétés lors de la génération de schémas JSON:
Services.AddswaggerGen (c => {... C.IgnoreObSoleProperties ();};
Vous pouvez omettre les opérations à partir de la sortie de fanfaronnade en décorant des actions individuelles ou en appliquant une large convention d'application.
Pour omettre une action spécifique, décorez-la avec le ApiExplorerSettingsAttribute
et définissez le drapeau IgnoreApi
:
[Httpget ("{id}")] [apiexplorersettings (ignorapi = true)] public produit getbyid (int id)
Pour omettre des actions par convention au lieu de les décorer individuellement, vous pouvez appliquer une convention d'action personnalisée. Par exemple, vous pouvez câbler la convention suivante pour documenter uniquement les opérations d'obtention:
// ApiExplorerGetsOnlyConvention.cspublic class ApiExplorerGetsOnlyConvention : IActionModelConvention{public void Apply(ActionModel action){action.ApiExplorer.IsVisible = action.Attributes.OfType<HttpGetAttribute>().Any();}}// Startup.cspublic void ConfigureServices(IServiceCollection Services) {Services.Addmvc (c => C.Conventions.add (Nouveau apiexploreRgetSonlyConvention ())); ...}
La spécification Swagger permet d'attribuer une ou plusieurs "balises" à une opération. Le générateur de fanfaronnade affectera le nom du contrôleur comme balise par défaut. Ceci est important à noter si vous utilisez le middleware SwaggerUI
car il utilise cette valeur pour regrouper les opérations.
Vous pouvez remplacer la balise par défaut en fournissant une fonction qui applique des balises par convention. Par exemple, la configuration suivante taguera, et donc les opérations de groupe dans l'interface utilisateur, par la méthode HTTP:
Services.AddswaggerGen (c => {... C.TagactionsBy (api => api.httpMethod);};
Par défaut, les actions sont commandées par TAG attribué (voir ci-dessus) avant d'être regroupés dans la structure imbriquée centrée sur le chemin de la spécification Swagger. Mais, vous pouvez modifier l'ordre par défaut des actions avec une stratégie de tri personnalisée:
Services.AddswaggerGen (c => {... C.OrderactionsBy ((apidesc) => $ "{apidesc.ActionDescriptor.Routevalues [" Controller "]} _ {apidesc.httpMethod}");};
Remarque: Cela dicte l'ordre de tri avant que les actions ne soient regroupées et transformées au format de fanfaronnade. Ainsi, cela affecte l'ordre des groupes (c'est-à-dire les "pathitems" de fanfaronniers) et l'ordre des opérations au sein d'un groupe, dans la sortie de fanfaronnade.
Si le générateur rencontre des types de paramètres ou de réponse complexes, il générera un schéma JSON correspondant, ajoutera-le au dictionnaire global components/schemas
et le référence à partir de la description de l'opération par ID unique. Par exemple, si vous avez une action qui renvoie un type Product
, le schéma généré sera référencé comme suit:
responses: { 200: { description: "OK", content: { "application/json": { schema: { $ref: "#/components/schemas/Product" } } } } }
Cependant, s'il rencontre plusieurs types avec le même nom, mais des espaces de noms différents (par exemple, RequestModels.Product
& ResponseModels.Product
. Dans ce cas, vous devrez fournir une stratégie d'identification personnalisée qui qualifie davantage le nom:
Services.AddswaggerGen (c => {... C.CustomSchemaids ((type) => type.fullName);};
Voir # 2703 pour soutenir les types imbriqués.
Swashbuckle, prêt à l'emploi, fait un travail décent pour générer des schémas JSON qui décrivent avec précision vos charges utiles de demande et de réponse. Cependant, si vous personnalisez le comportement de sérialisation pour certains types de votre API, vous devrez peut-être l'aider.
Par exemple, vous pouvez avoir une classe avec plusieurs propriétés que vous souhaitez représenter dans JSON en tant que chaîne séparée par des virgules. Pour ce faire, vous implémenteriez probablement un JsonConverter
personnalisé. Dans ce cas, Swashbuckle ne sait pas comment le convertisseur est mis en œuvre et vous devez donc lui fournir un schéma qui décrit avec précision le type:
// phonenumber.cspublic classe phonenumber {public String countrycode {get; ensemble; } public String AreaCode {get; ensemble; } public String subsonné abonné {get; ensemble; }} // startup.csservices.addswaggerGen (c => {... c.maptype <hoLenumber> (() => new OpenApischema {type = "String"});};
Swashbuckle expose un pipeline de filtre qui s'accroche au processus de génération. Une fois générés, les objets de métadonnées individuels sont passés dans le pipeline où ils peuvent être modifiés davantage. Vous pouvez câbler les filtres personnalisés pour enrichir les "opérations", "schémas" et "documents" générés.
Swashbuckle récupère une ApiDescription
, faisant partie du noyau ASP.NET, pour chaque action et l'utilise pour générer une OpenApiOperation
correspondante. Une fois généré, il passe l' OpenApiOperation
et l' ApiDescription
via la liste des filtres d'opération configurés.
Dans une implémentation de filtre typique, vous inspecteriez l' ApiDescription
pour les informations pertinentes (par exemple, les informations d'itinéraire, les attributs d'action, etc.), puis mettent à jour l' OpenApiOperation
en conséquence. Par exemple, le filtre suivant répertorie une réponse "401" supplémentaire pour toutes les actions décorées de l' AuthorizeAttribute
:
// AuthResponSesOperationFilter.Cspublic AuthResponSesOpperationFilter: iOperationFilter {public void appliquez (OpenaPioperation Operation, OperationFilterClaintex izeattribute > (); if (authAtTributes.Any ()) operation.Responses.add ("401", new OpenAPiResponse {Description = "Unauthorized"});}} // startup.csservices.addswaggergen (c => {... C.OperationFilter <AuthResponSesOperationFilter> ();};
Remarque: les pipelines filtrants sont di-aware. Autrement dit, vous pouvez créer des filtres avec des paramètres du constructeur et si les types de paramètres sont enregistrés avec le framework DI, ils seront automatiquement injectés lorsque les filtres seront instanciés
Swashbuckle génère un Jsonschema à saveur de fanfaronnade pour chaque paramètre, réponse et type de propriété exposé par vos actions de contrôleur. Une fois généré, il passe le schéma et tape via la liste des filtres de schéma configurés.
L'exemple ci-dessous ajoute une extension du fournisseur Autorest (voir https://github.com/azure/autorest/blob/master/docs/extensions/readme.md#x-ms-enum) pour informer l'outil Autorest comment les énumations doivent être modélisées quand il génère le client API.
// Autorestschemafilter.cspublic classe AutorestSchemafilter: IschemaFilter {public void applique (schéma openapischema, schémafilterContext context) {var type = context.type; if (type.isenum) {schema.extensions.add ("x-mens-ennum", new OpenAPiObject {["name"] = new OpenApistring (type.name), ["ModelAssTring"] = new OpenApiBooliean (true)});};}} // startup.csservices.addswaggerGen (c => {... C .SchemaFilter <autorestSchemaFilter> ();};
L'exemple ci-dessous permet une génération de schéma automatique d'objets Generic Dictionary<Enum, TValue>
. Notez que cela ne génère que le fanfaron; System.Text.Json
n'est pas en mesure d'analyser les énumérations de Dictionary par défaut, vous aurez donc besoin d'un JSONConverter spécial, comme dans les documents .NET
// dictionarytkeyenumtvalueschemafilter.cspublic class dictionarytkeyenumtvalueschemafilter: ischemafilter { public void s'appliquent (schéma openapischema, contexte SchemaFilterContext) {// Exécutez uniquement pour des champs qui sont un dictionnaire <enum, tvalue> if (! Context.type.isgenerictype ||! Context.type.getGenericTedEfinition (). IsAssignableFrom (typeof (dictionary <,>))) {return;} var keyType = context.type.getGenericArguments () [0]; var valetype = context.type.getGenericArguments () [1]; if (! keyType.isenum) {return;} schema.type = "objet"; schema.properties = keyType.getEnUms (). todictionary (name => name, name => context.scheMagenerator.GenerateSchema (valléeype, context.scheMaRepository)); }} // startup.csservices.addswaggergen (c => {... // Ceux-ci seront remplacés par DictionaryTkeyEnumTvalueschemaFilter, mais vous êtes nécessaire pour éviter une erreur.// vous en aurez besoin pour tous les types de dictionnaire <,> vous avez .C.MapType <dictionnaire <Myenum, liste <string >>> (() => new OpenApischema ()); c.schemafilter <dictionarytkeyenumtvalueschemafilter> ();};
Une fois qu'un OpenApiDocument
a été généré, il peut également être passé par un ensemble de filtres de documents préconfigurés. Cela donne un contrôle total pour modifier le document comme bon vous semble. Pour vous assurer que vous retournez toujours Swagger JSON valide, vous devriez avoir une lecture de la spécification avant d'utiliser ce type de filtre.
L'exemple ci-dessous fournit une description de toutes les balises affectées aux opérations dans le document:
classe publique TagDescrisesDocumentFilter: idocumentFilter {public void appliquez (openAPiDocument swaggerdoc, documentFilterContext context) {swaggerdoc.tags = new list <openapitag> {new OpenApitag {name = "Products", Description = "Browse / Gérer le catalogue de produits"},, new OpenaPitag " {Name = "ordres", description = "Soumettre les ordres"}};}}
Remarque: Si vous utilisez le middleware SwaggerUI
, les TagDescriptionsDocumentFilter
démontré ci-dessus pourraient être utilisés pour afficher des descriptions supplémentaires à côté de chaque groupe d'opérations.
Dans Swagger, vous pouvez décrire comment votre API est sécurisée en définissant un ou plusieurs schémas de sécurité (par exemple, Basic, Key API, OAuth2 etc.) et déclarant lequel de ces schémas est applicable à l'échelle mondiale ou pour des opérations spécifiques. Pour plus de détails, jetez un œil à l'objet exigence de sécurité dans la spécification Swagger.
Dans Swashbuckle, vous pouvez définir des schémas en invoquant la méthode AddSecurityDefinition
, en fournissant un nom et une instance d' OpenApiSecurityScheme
. Par exemple, vous pouvez définir un débit OAuth 2.0 - comme suit:
// startup.csservices.addswaggerGen (c => {... // Définissez le schéma OAuth2.0 qui est utilisé (c'est-à-dire un flux implicite) C.AddSecUrityDefinition ("OAuth2", New OpenApisecurityScheme {Type = SecurityScheMetype.Oauth2, Flows = Nouveau openapioAuthflows {implicit = new OpenAPioAuthFlow {AuthorizationUrl = new Uri ("/ Auth-Server / Connect / Authorize", urikind.relative), Scopes = new Dictionary <String, String> {{"readAccess", "Access Read Operations"} , {"WriteAccess", "Access Write Operations"}}}}});};
Remarque: En plus de définir un schéma, vous devez également indiquer quelles opérations ce schéma est applicable. Vous pouvez appliquer des schémas à l'échelle mondiale (c'est-à-dire à toutes les opérations) via la méthode AddSecurityRequirement
. L'exemple ci-dessous indique que le schéma appelé "oAuth2" devrait être appliqué à toutes les opérations et que les étendues "ReadAccess" et "WriteAccess" sont nécessaires. Lors de l'application de schémas de type autre que "OAuth2", le tableau des portées doit être vide.
C.AddswaggerGen (c => {... C.AddSecurityRequimentment (new OpenAPiSecurityRequiment {{new OpenAPisecurityScheme {Reference = new OpenaPireference {Type = REFORENCETYPE.SecurityScheme, id = "OAuth2"}}, new [] {"readAccess", " WriteAccess "}}});})
Si vous avez des schémas qui ne sont applicables que pour certaines opérations, vous pouvez les appliquer via un filtre d'opération. Par exemple, le filtre suivant ajoute des exigences OAuth2 en fonction de la présence de l' AuthorizeAttribute
:
// SecurityRequirementsOperationFilter.Cspublic Classe SecurityRequirementsOperationFilter: iOperationFilter {public void appliquez (OpenAperation Operation, OperationFilterContex > att.policy) .distinct (); if (requiredscopes.any ()) {operation.Responses.add ("401", new OpenApireSponse {description = "Unauthorized"}); operation.Responses.add ("403", new OpenApiResponse {description = "Forbidden"}); var oauthscheme = new OpenAPiSecurityScheme {Reference = new OpenaPireference {type = RefercenceType.SecurityScheme, id = "oAuth2"}}; operation.security = new List <OpenapiSucyrequirement> {new OpenApiSecurityRequirement {[ouverte { oAuthscheme] = requiredScopes.tolist ()}};}}}
Remarque: Si vous utilisez le middleware SwaggerUI
, vous pouvez activer les flux OAuth2.0 interactifs qui sont alimentés par les métadonnées de sécurité émises. Voir Activation des flux OAuth2.0 pour plus de détails.
Services.AddswaggerGen (c => {C.AddSecurityDefinition ("BearerAuth", new OpenAPiSecurityScheme {Type = SecurityScheMetype.http, schéma = "Bearer", BearerFormat = "JWT", Description = "JWT Authorization Header Using the Bearer Scheme."} );
Swagger / OpenAPI définit les mots clés allOf
et oneOf
pour décrire les relations d'héritage et de polymorphisme dans les définitions de schéma. Par exemple, si vous utilisez une classe de base pour des modèles qui partagent des propriétés communes, vous pouvez utiliser le mot-clé allOf
pour décrire la hiérarchie des successions. Ou, si votre sérialiseur prend en charge la sérialisation / désérialisation polymorphe, vous pouvez utiliser le mot-clé oneOf
pour documenter tous les schémas "possibles" pour les demandes / réponses qui varient selon le sous-type.
Par défaut, Swashbuckle aplatit les hiérarchies de l'héritage. Autrement dit, pour les modèles dérivés, les propriétés héritées sont combinées et répertoriées aux côtés des propriétés déclarées. Cela peut provoquer beaucoup de duplication dans le fanfaron généré, en particulier lorsqu'il y a plusieurs sous-types. Il est également problématique si vous utilisez un générateur de clients (par exemple NSWAG) et que vous souhaitez maintenir la hiérarchie d'héritage dans les modèles clients générés. Pour contourner cela, vous pouvez appliquer le paramètre UseAllOfForInheritance
, et cela tirera parti du mot-clé allOf
pour incorporer les propriétés héréditaires par référence dans le fanfaron généré:
Circle: { type: "object", allOf: [ { $ref: "#/components/schemas/Shape" } ], properties: { radius: { type: "integer", format: "int32", } }, }, Shape: { type: "object", properties: { name: { type: "string", nullable: true, } }, }
Si votre sérialiseur prend en charge la sérialisation / désérialisation polymorphe et que vous souhaitez répertorier les sous-types possibles pour une action qui accepte / renvoie des types de base abstraits, vous pouvez appliquer le paramètre UseOneOfForPolymorphism
. En conséquence, les schémas de demande / réponse générés feront référence à une collection de schémas "possibles" au lieu du schéma de classe de base:
requestBody: { content: { application/json: { schema: { oneOf: [ { $ref: "#/components/schemas/Rectangle" }, { $ref: "#/components/schemas/Circle" }, ], } } }
Comme les relations d'héritage et de polymorphisme peuvent souvent devenir assez complexes, non seulement dans vos propres modèles, mais aussi dans la bibliothèque de classe .NET, Swashbuckle est sélectif sur les hiérarchies qu'elle fait et n'expose pas dans le fanfaron généré. Par défaut, il ramassera tous les sous-types définis dans le même assemblage qu'un type de base donné. Si vous souhaitez remplacer ce comportement, vous pouvez fournir une fonction de sélecteur personnalisée:
Services.AddswaggerGen (C => {... C.UTEALLOFFORINHERITANCE (); C.SelectSubTypeSusing (Basetype => {return typeof (startup) .assembly.getTypes (). Where (Type => Type.issubClassof (Basetype)); })});
Remarque: Si vous utilisez la bibliothèque d'annotations Swashbuckle, il contient un sélecteur personnalisé basé sur la présence d'attributs SwaggerSubType
sur les définitions de classe de base. De cette façon, vous pouvez utiliser des attributs simples pour énumérer explicitement les relations d'héritage et / ou de polymorphisme que vous souhaitez exposer. Pour activer ce comportement, consultez les documents d'annotations.
En conjonction avec les mots clés oneOf
et / ou allOf
, Swagger / OpenAPI prend en charge un champ discriminator
sur les définitions de schéma de base. Ce mot-clé pointe vers la propriété qui identifie le type spécifique représenté par une charge utile donnée. En plus du nom de la propriété, la description du discriminateur peut également inclure un mapping
qui mappe les valeurs discriminatrices à des définitions de schéma spécifiques.
Par exemple, le sérialiseur NewTonsoft prend en charge la sérialisation / désérialisation polymorphe en émettant / en acceptant une propriété "$ type" sur les instances JSON. La valeur de cette propriété sera le nom de type qualifié d'assemblage du type représenté par une instance JSON donnée. Ainsi, pour décrire explicitement ce comportement dans Swagger, le schéma de demande / réponse correspondant pourrait être défini comme suit:
components: { schemas: { Shape: { required: [ "$type" ], type: "object", properties: { $type: { type": "string" }, discriminator: { propertyName: "$type", mapping: { Rectangle: "#/components/schemas/Rectangle", Circle: "#/components/schemas/Circle" } } }, Rectangle: { type: "object", allOf: [ { "$ref": "#/components/schemas/Shape" } ], ... }, Circle: { type: "object", allOf: [ { "$ref": "#/components/schemas/Shape" } ], ... } } }
Si UseAllOfForInheritance
ou UseOneOfForPolymorphism
est activé et que votre sérialiseur prend en charge (et a permis) d'émettre / d'accepter une propriété de discriminatrice, Swashbuckle générera automatiquement les métadonnées discriminator
correspondantes sur les définitions de schéma de base.
Alternativement, si vous avez personnalisé votre sérialiseur pour prendre en charge la sérialisation / désérialisation polymorphe, vous pouvez fournir des fonctions de sélecteur personnalisées pour déterminer le nom du discriminateur et la cartographie correspondante:
Services.AddswaggerGen (c => {... C.UseOneOfforInheritance (); C.SelectDiscriminatorNameusing ((Basetype) => "TynEname"); C.SelectDiscriminatorValueUsing ((subtype) => subtype.name);});
Remarque: Si vous utilisez la bibliothèque Annotations Swashbuckle, il contient des fonctions de sélecteur personnalisées basées sur la présence de SwaggerDiscriminator
et SwaggerSubType
sur les définitions de classe de base. De cette façon, vous pouvez utiliser des attributs simples pour fournir explicitement des métadonnées discriminatrices. Pour activer ce comportement, consultez les documents d'annotations.
Par défaut, l'interface utilisateur de Swagger sera exposée à "/ Swagger". Si nécessaire, vous pouvez modifier cela lorsque vous activez le middleware Swaggerui:
app.useswaggerui (c => {c.RoutePrefix = "api-docs"}
Par défaut, l'interface utilisateur de Swagger aura un titre de document générique. Lorsque vous avez plusieurs pages de fanfaronniers, il peut être difficile de les distinguer. Vous pouvez modifier cela lorsque vous activez le middleware Swaggerui:
app.useswaggerui (c => {c.DocumentTitle = "My Swagger UI";}
Par défaut, l'interface utilisateur de Swagger inclut CSS et JS par défaut, mais si vous souhaitez modifier le chemin ou l'URL (par exemple pour utiliser un CDN):
app.useswaggerui (c => {c.stylespath = "https://cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui.min.css"; c.scriptbundlepath = "https : //cdnjs.cloudflare.com/ajax/libs/swagger-ui/5.17.10/swagger-ui-bundle.min.js "; c.scriptpresetspath =" https://cdnjs.cloudflare.com/ajax/libs /wagger-Ui/5.17.10/swagger-ui-standalone-preset.min.js ";}
Lorsque vous activez le middleware, vous avez besoin de spécifier un ou plusieurs points de terminaison Swagger (entièrement qualifiés ou par rapport à la page d'interface utilisateur) pour alimenter l'interface utilisateur. Si vous fournissez plusieurs points de terminaison, ils seront répertoriés dans le coin supérieur droit de la page, permettant aux utilisateurs de basculer entre les différents documents. Par exemple, la configuration suivante pourrait être utilisée pour documenter différentes versions d'une API.
app.useswaggerui (c => {c.swaggerendpoint ("/ swagger / v1 / swagger.json", "v1 docs"); c.swaggerendpoint ("/ swagger / v2 / swagger.json", "v2 docs"); }
Le Swagger-UI est livré avec son propre ensemble de paramètres de configuration, tous décrits ici. Dans Swashbuckle, la plupart d'entre eux sont surfacés à travers les options de middleware Swaggerui:
app.useswaggerui (c => {C.DefaultModelexpandDepth (2); C.DefaultModelRendering (ModelRendering.Model); C.DefaultModelSExPandDepth (-1); C.DisplayOprationId (); C.DisplayRequestDuration (); C.DocexPansion (Docexpansion. Aucun); ["MyCustomPlugin"]; C.EnableValidator (); ) => {Retour Response;} ");});
Note
Lorsque vous ajoutez des plugins personnalisés, assurez-vous d'ajouter tous les fichiers js
personnalisés qui définissent les fonctions de plugin.
Pour modifier le comportement, vous pouvez injecter des fichiers JavaScript supplémentaires en les ajoutant à votre dossier wwwroot
et en spécifiant les chemins relatifs dans les options de middleware:
app.useswaggerui (c => {c.injectjavascript ("/ swagger-ui / coustom.js");}
Remarque: Les options InjectOnCompleteJavaScript
et InjectOnFailureJavaScript
ont été supprimées car la dernière version de Swagger-UI n'expose pas les crochets nécessaires. Au lieu de cela, il fournit un système de personnalisation flexible basé sur des concepts et des modèles de React et Redux. Pour en tirer parti, vous devrez fournir une version personnalisée d'Index.html comme décrit ci-dessous.
L'application Custom Index Exemple démontre cette approche, à l'aide du système de plugin Swagger-UI, fournit une barre supérieure personnalisée et pour masquer le composant Info.
Pour modifier l'apparence et la sensation, vous pouvez injecter des feuilles de style CSS supplémentaires en les ajoutant à votre dossier wwwroot
et en spécifiant les chemins relatifs dans les options de middleware:
app.useswaggerui (c => {C.InjectStylesHeet ("/ swagger-ui / coustom.css");}
Pour personnaliser l'interface utilisateur au-delà des options de base énumérées ci-dessus, vous pouvez fournir votre propre version de la page Swagger-UI index.html:
app.useswaggerui (c => {c.indexstream = () => getType (). assembly .getManifestResourceStream ("CustomuiIndex.swagger.index.html"); // nécessite des fichiers pour être ajoutés en tant que ressource embarquée});
Pour commencer, vous devez baser votre index personnalisé.html sur la version par défaut
Le Swagger-UI a un soutien intégré pour participer aux flux d'autorisation OAuth2.0. Il interagit avec l'autorisation et / ou les points de terminaison des jetons, comme spécifié dans le JSON Swagger, pour obtenir des jetons d'accès pour les appels API ultérieurs. Voir l'ajout de définitions de sécurité et les exigences pour un exemple d'ajout de métadonnées OAuth2.0 au fanfaron généré.
Si votre point de terminaison Swagger comprend les métadonnées de sécurité appropriées, l'interaction UI doit être automatiquement activée. Cependant, vous pouvez personnaliser davantage le support OAuth dans l'interface utilisateur avec les paramètres suivants ci-dessous. Voir la documentation Swagger-UI pour plus d'informations:
app.useswaggerui (c => {c.oAuthClientid ("test-id"); c.oAuthClientECret ("test-secret"); c.oauthUsername ("test-user"); c.oauthrealm ("test-realm" ))). String, String> {{"foo", "bar"}});
Pour utiliser des intercepteurs personnalisés sur les demandes et les réponses passant par Swagger-UI, vous pouvez les définir comme des fonctions JavaScript dans la configuration:
app.useswaggerui (c => {c.UseRequestInterceptor ("(req) => {req.headers ['x-my-custom-header'] = 'myCustomValue'; return req;}"); c.UserSponseConInterceptor (" (res) => {console.log ('réponse interceptrice personnalisée de:', res.url);
Cela peut être utile dans une gamme de scénarios où vous voudrez peut-être ajouter des jetons XSRF locaux à toutes les demandes par exemple:
app.useswaggerui (c => {C.UseRequestInterceptor ("(req) => {req.heders ['x-xsrf-token'] = localStorage.getItem ('xsrf-token'); return req;}"); });
Installez le package NuGet suivant dans votre application ASP.NET CORE.
Package Manager : Install-Package Swashbuckle.AspNetCore.Annotations CLI : dotnet add package Swashbuckle.AspNetCore.Annotations
Dans la méthode ConfigureServices
de Startup.cs
, activez les annotations dans le bloc de configuration de Swagger:
Services.AddswaggerGen (c => {... C.EnableAnNotations ();});
Une fois les annotations activées, vous pouvez enrichir les métadonnées de l'opération générées en décorant des actions avec un SwaggerOperationAttribute
.
[Httppost] [SwaggerOperation (résumé = "Crée un nouveau produit", description = "Required Privileges", OperationId = "CreateProduct", Tags = new [] {"Achat", "Products"})] public IacseRresult Create ([[[[ From body] produit produit)
ASP.NET CORE fournit le ProducesResponseTypeAttribute
pour répertorier les différentes réponses qui peuvent être renvoyées par une action. Ces attributs peuvent être combinés avec des commentaires XML, comme décrit ci-dessus, pour inclure des descriptions amies humaines avec chaque réponse dans le fanfaron généré. Si vous préférez faire tout cela avec un seul attribut et éviter l'utilisation de commentaires XML, vous pouvez plutôt utiliser SwaggerResponseAttribute
S:
[HTTPPOST] [SwaggerSResponse (201, "Le produit a été créé", typeof (produit))] [SwaggerSResponse (400, "Les données du produit sont invalides")] Public IaCectionResult Create ([FromBody] Product Product)
Vous pouvez annoter "chemin", "requête" ou "en-tête" par des paramètres ou propriétés liés (c'est-à-dire décorés de [FromRoute]
, [FromQuery]
ou [FromHeader]
) avec un SwaggerParameterAttribute
pour enrichir les métadonnées Parameter
correspondantes générées par Swashbuckle:
[Httpget] public iActionResult getProducts ([FromQuery, swaggerparameter ("Rechercher des mots clés", obligatoire = true)] String Mots-clés)
Vous pouvez annoter les paramètres ou les propriétés liés "Body" (c'est-à-dire décorés avec [FromBody]
) avec un SwaggerRequestBodyAttribute
pour enrichir les métadonnées RequestBody
correspondantes générées par Swashbuckle:
[HTTPPOST] Public IactionResult CreateProduct ([FromBody, SwaggerRequestbody ("La charge utile du produit", obligatoire = true)] Produit produit)
Vous pouvez annoter des classes ou des propriétés avec un SwaggerSchemaAttribute
pour enrichir les métadonnées Schema
correspondantes générées par Swashbuckle:
[Swaggerschema (requis = new [] {"Description"})] public public Product {[swaggerschema ("L'identifiant de produit", readonly = true)] public int id {get; ensemble; } [Swaggerschema ("La description du produit")] Public String Description {get; ensemble; } [Swaggerschema ("La date à laquelle il a été créé", format = "date")] public datetime dateCreated {get; ensemble; }}
Remarque: Dans Swagger / OpenAPI, les objets sérialisés et les propriétés contenues sont représentés sous forme d'instances Schema
, d'où la raison pour laquelle cette annotation peut être appliquée aux classes et aux propriétés. Les propriétés "requises" sont également spécifiées comme un tableau de noms de propriétés sur le schéma de niveau supérieur par opposition à un drapeau sur chaque propriété individuelle.
Le package SwaggerGen
fournit plusieurs points d'extension, y compris les filtres de schéma (décrits ici) pour personnaliser tous les schémas générés. Cependant, il peut y avoir des cas où il est préférable d'appliquer un filtre à un schéma spécifique. Par exemple, si vous souhaitez inclure un exemple pour un type spécifique dans votre API. Cela peut être fait en décorant le type avec un SwaggerSchemaFilterAttribute
:
// product.cs [swaggerschemafilter (typeof (productschemafilter))] produit public de classe {...} // productschemafilter.cspublic productschemafilter: ischemafilter {public void applaiter (openapischema schéma, schemafiltercontex ["Id"] = new OpenAPiInteger (1), ["Description"] = new OpenAPistring ("un produit génial")};}}
Par défaut, le générateur de swagger étiquetera toutes les opérations avec le nom du contrôleur. Cette balise est ensuite utilisée pour conduire les groupes d'opération dans le Swagger-UI. Si vous souhaitez fournir une description pour chacun de ces groupes, vous pouvez le faire en ajoutant des métadonnées pour chaque balise de nom de contrôleur via le SwaggerTagAttribute
:
[Swaggertag ("Créer, lire, mettre à jour et supprimer des produits")] public Class ProductsController {...}
Remarque: Cela ajoutera la description ci-dessus spécifiquement à la balise nommée "Produits". Par conséquent, vous devez éviter d'utiliser cet attribut si vous étiquetez les opérations avec autre chose que le nom du contrôleur - par exemple si vous personnalisez le comportement de marquage avec TagActionsBy
.
Si vous souhaitez utiliser le comportement de l'héritage et / ou du polymorphisme de Swashbuckle, vous pouvez utiliser des annotations pour indiquer explicitement les sous-types "connus" pour un type de base donné. Cela remplacera la fonction de sélecteur par défaut, qui sélectionne tous les sous-types dans le même assemblage que le type de base, et doit donc être explicitement activé lorsque vous activez les annotations:
// startup.csservices.addswaggerGen (c => {C.EnableAnNotations (pertineanNotationsForInheritance: true, perdableAnnotationsForPolymormism: true);}); // shape.cs [swaggersubtype (TypeOf) ] Forme de classe abstraite publique {}
Si vous utilisez des annotations pour indiquer explicitement les sous-types "connus" pour un type de base polymorphe, vous pouvez combiner le SwaggerDiscriminatorAttribute
avec le SwaggerSubTypeAttribute
pour fournir des métadonnées supplémentaires sur la propriété "discriminatrice", qui sera ensuite incorporée dans la définition du schéma généré:
// startup.csservices.addswaggerGen (c => {C.EnableAnNotations (perturboTationsForHheritance: true, perteannotationsforpolymorphism: true);}); // shape.cs [swaggerdiscriminator ("shapetype")] [swaggersubtype (typeof (rEctGrand), DismiminatorValuue) = "rectangle")] [swaggersubType (typeof (cercle), discriminatorValue = "Circle")] Forme de classe abstraite publique {public shapetype {get; ensemble; }}
Cela indique que la charge utile correspondante aura une propriété "Shapetype" pour distinguer les sous-types, et que la propriété aura une valeur de "rectangle" si la charge utile représente un type Rectangle
et une valeur de "cercle" s'il représente un type Circle
. Ce détail sera décrit dans la définition du schéma généré comme suit:
schema: { oneOf: [ { $ref: "#/components/schemas/Rectangle" }, { $ref: "#/components/schemas/Circle" }, ], discriminator: { propertyName: shapeType, mapping: { rectangle: "#/components/schemas/Rectangle", circle: "#/components/schemas/Circle", } } }
Une fois que votre application a été configurée avec Swashbuckle (voir Mise en route), vous pouvez utiliser l'outil CLI Swashbuckle pour récupérer Swagger / OpenAPI JSON directement à partir de l'assemblage de démarrage de votre application et écrivez-le dans le fichier. Cela peut être utile si vous souhaitez incorporer la génération de fanfaronniers dans un processus CI / CD, ou si vous souhaitez le servir à partir du fichier statique au moment de l'exécution.
Il est emballé comme un outil .NET qui peut être installé et utilisé via le SDK DOTNET.
️ L'outil doit charger votre DLL de démarrage et ses dépendances à l'exécution. Par conséquent, vous devez utiliser une version du SDKdotnet
qui est compatible avec votre application. Par exemple, si votre application ciblenet6.0
, vous devez utiliser la version 6.0.xxx du SDK pour exécuter l'outil CLI. S'il ciblenet8.0
, vous devez utiliser la version 8.0.xxx du SDK et ainsi de suite.
Installer comme un outil global
dotnet tool install -g Swashbuckle.AspNetCore.Cli
Vérifiez que l'outil a été installé correctement
swagger tofile --help
Générez un document Swagger / OpenAPI à partir de l'assemblage de démarrage de votre application
swagger tofile --output [output] [startupassembly] [swaggerdoc]
Où ...
[Sortie] est le chemin relatif où le JSON Swagger sera sorti pour
[StartupAssembly] est le chemin relatif de l'assemblage de démarrage de votre application
[Swaggerdoc] est le nom du document Swagger que vous souhaitez récupérer, comme configuré dans votre classe de démarrage
Dans la racine de votre projet, créez un fichier de manifeste d'outils:
dotnet new tool-manifest
Installer comme un outil local
dotnet tool install Swashbuckle.AspNetCore.Cli
Vérifiez que l'outil a été installé correctement
dotnet swagger tofile --help
Générez un document Swagger / OpenAPI à partir de l'assemblage de démarrage de votre application
dotnet swagger tofile --output [output] [startupassembly] [swaggerdoc]
Où ...
[Sortie] est le chemin relatif où le JSON Swagger sera sorti pour
[StartupAssembly] est le chemin relatif de l'assemblage de démarrage de votre application
[Swaggerdoc] est le nom du document Swagger que vous souhaitez récupérer, comme configuré dans votre classe de démarrage
L'exécution de l'outil s'exécutera dans le contexte d'un hôte Web "par défaut". Cependant, dans certains cas, vous souhaiterez peut-être apporter votre propre environnement hôte, par exemple si vous avez configuré un conteneur DI personnalisé tel que AutoFAC. Pour ce scénario, l'outil CLI Swashbuckle expose un crochet basé sur la convention pour votre application.
Autrement dit, si votre application contient une classe qui répond à l'une des conventions de dénomination suivantes, cette classe sera utilisée pour fournir un hôte pour que l'outil CLI s'exécute.
public class SwaggerHostFactory
, contenant une méthode statique publique appelée CreateHost
avec le type de retour IHost
public class SwaggerWebHostFactory
, contenant une méthode statique publique appelée CreateWebHost
avec le retour de type IWebHost
Par exemple, la classe suivante pourrait être utilisée pour tirer parti de la même configuration d'hôte que votre application:
classe publique SwaggerHostFactory {public static ihost createhost () {return programme.CreateHostBuilder (nouvelle chaîne [0]). build ();}}
Par défaut, l'interface utilisateur Redoc sera exposée à "/ api-docs". Si nécessaire, vous pouvez modifier cela lorsque vous activez le middleware Redoc:
app.useredoc (c => {c.RoutePrefix = "docs" ...}
Par défaut, l'interface utilisateur Redoc aura un titre de document générique. Vous pouvez modifier cela lorsque vous activez le middleware Redoc:
app.Useredoc (c => {c.DocumentTitle = "Mes documents API"; ...}
Redoc est livré avec son propre ensemble de paramètres de configuration, tous décrits ici https://github.com/rebilly/redoc/blob/main/readme.md#redoc-options-object. Dans Swashbuckle, la plupart d'entre eux sont surfacés à travers les options de middleware Redoc:
app.Useredoc (c => {C.Specurl ("/ V1 / Swagger.json"); C.EnableTrustedSpec (); C.ScrollyOffset (10); C.HideHostName (); C.HidedownloadButton (); C.Expandresses ("200.201"); Sortpropsalphabetical ();});
L'utilisation de c.SpecUrl("/v1/swagger.json")
plusieurs fois dans le même UseReDoc(...)
n'ajoutera pas plusieurs URL.
Pour modifier l'apparence et la sensation, vous pouvez injecter des feuilles de style CSS supplémentaires en les ajoutant à votre dossier wwwroot
et en spécifiant les chemins relatifs dans les options de middleware:
app.Useredoc (c => {... C.InjectStylesHeet ("/ redoc / coustom.css");}
Il est également possible de modifier le thème en utilisant la propriété AdditionalItems
, voir https://github.com/rebilly/redoc/blob/main/readme.md#redoc-options-object pour plus d'informations.
app.Useredoc (c => {... C.ConfigObject.Additionalitems = ...}
Pour personnaliser l'interface utilisateur au-delà des options de base énumérées ci-dessus, vous pouvez fournir votre propre version de la page REDOC index.html:
app.Useredoc (c => {c.indexstream = () => getType (). Assembly .getManifestResourceStream ("CustomIndex.redoc.index.html"); // nécessite un fichier pour être ajouté en tant que ressource intégrée});
Pour commencer, vous devez baser votre index personnalisé.html sur la version par défaut