web-dev-qa-db-fra.com

Comment puis-je créer un chemin d'URL dans Swashbuckle / Swaggerwork lorsque l'API est servie depuis un autre projet?

tout. J'essaie de documenter un WebApi 2 en utilisant le package Swashbuckle.

Tout fonctionne très bien si l'API s'exécute seule, c'est-à-dire localhost/api/swagger m'amène à ui et localhost/api/swagger/docs/v1 à json.

Cependant, l'application producation initialise ce même projet Webapi en exécutant la méthode webapiconfig de ce projet à partir de global.asax.cs dans un autre projet Web (maintenant l'application principale). Ainsi, l'url de l'API ressemble à localhost/web/api au lieu de localhost/api.

Maintenant, le swashbuckle ne fonctionne pas du tout comme ça.

  • localhost/api/swagger génère une erreur ne peut pas charger 'API.WebApiApplication', bien sûr
  • localhost/web/swagger = 404
  • localhost/web/api/swagger = 404

J'ai essayé de regarder partout, mais tout ce que j'ai trouvé est une solution de contournement.

c.RootUrl(req => req.RequestUri.GetLeftPart(UriPartial.Authority) + VirtualPathUtility.ToAbsolute("~/").TrimEnd('/'));

Malheureusement, cela ne fonctionne pas, maintenant peut-être que cela devrait et je dois juste changer quelque chose, mais je ne sais même pas exactement ce que cette propriété attend et à quoi elle devrait être définie.

Peut-être que ce n'est même pas applicable - peut-être que la configuration que nous avons nécessite quelque chose d'autre ou quelques changements de code de swashbuckle.

J'apprécierai toute aide que vous pourrez apporter. J'ai vraiment commencé à aimer swagger (et swashbuckle) pour la documentation de repos.

14
Dmitriy

Pour Swashbuckle 5.x:

Cela semble être défini par ne méthode d'extension de httpConfiguration appelée EnableSwagger . Swashbuckle 5.x readme de migration note que cela remplace SwaggerSpecConfig. SwaggerDocConfig RootUrl () remplace spécifiquement ResolveBasePathUsing () à partir de 4.x.

Cela fonctionne pratiquement de la même manière qu'avant, il semble que le plus grand changement ait été qu'il a été renommé et déplacé dans SwaggerDocConfig :

public void RootUrl(Func<HttpRequestMessage, string> rootUrlResolver)

Un exemple tiré du readme , modifié pour plus de concision:

string myCustomBasePath = @"http://mycustombasepath.com";

httpConfiguration
    .EnableSwagger(c =>
        {
            c.RootUrl(req => myCustomBasePath);

            // The rest of your additional metadata goes here
        });

Pour Swashbuckle 4.x:

Utilisez SwaggerSpecConfig ResolveBasePathUsing et demandez à votre lambda de lire votre point de terminaison connu.

ResolveBasePathUsing:

public SwaggerSpecConfig ResolveBasePathUsing(Func<HttpRequestMessage, string> basePathResolver);

Mon API est derrière un équilibreur de charge et cela a été une solution de contournement utile pour fournir une adresse de base. Voici un exemple stupide pour utiliser ResolveBasePathUsing pour résoudre le chemin d'accès avec un chemin de base connu.

string myCustomBasePath = @"http://mycustombasepath.com";

SwaggerSpecConfig.Customize(c =>
{
    c.ResolveBasePathUsing((req) => myCustomBasePath);
}

J'ai codé en dur le point final pour plus de clarté, mais vous pouvez le définir n'importe où. Vous pouvez même tilisez l'objet request pour tenter de nettoyer votre uri de requête pour pointer vers/web/api au lieu de/api.

Le développeur a commenté cette solution sur GitHub l'année dernière:

Le lambda prend la requête HttpRequest actuelle (c'est-à-dire la demande pour une déclaration Swagger ApiDeclaration) donnée et doit renvoyer une chaîne à utiliser comme baseUrl pour votre Api. Pour les applications à charge équilibrée, cela devrait renvoyer le chemin d'équilibrage de charge.

L'implémentation par défaut est la suivante:

(req) => req.RequestUri.GetLeftPart(UriPartial.Authority) +  req.GetConfiguration().VirtualPathRoot.TrimEnd('/');

...

Concernant les chemins relatifs, la spécification Swagger nécessite des chemins absolus car l'URL à laquelle le Swagger est servi n'est pas nécessairement l'URL de l'API réelle.

...

Le lambda reçoit une instance HttpRequestMessage ... vous devriez pouvoir l'utiliser pour obtenir le RequestUri etc. Une autre option, vous pouvez simplement placer le nom d'hôte dans votre web.config et demander au lambda de le lire à partir de là.

17
Anthony Neace