Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default Configuration Should Respect Application Root #171

Closed
mclark1129 opened this issue Sep 6, 2016 · 2 comments
Closed

Default Configuration Should Respect Application Root #171

mclark1129 opened this issue Sep 6, 2016 · 2 comments
Milestone

Comments

@mclark1129
Copy link

This is similar to #139 but the suggested workaround is not sufficient in my case. We typically code our applications to be agnostic of the folder structure they are deployed. That means that we aren't able to hardcode a base URL in the startup method. Previously in 5x I was able to use the RootUrl configuration method to inspect the incoming request to generate the correct Swagger URL.

c.RootUrl(req => {                        
var pathBase = req.GetOwinContext().Get<string>("owin.RequestPathBase");
          return new Uri(
              req.RequestUri.ToString().Replace(
              req.RequestUri.PathAndQuery, string.Empty) 
              + pathBase).ToString();
});

In the overload the UseSwaggerUi() method only accepts a static string. If it was possible to provide it a lambda to generate the URL on request then I could recreate my previous workaround.

That being said, is there a reason the generated UI application has to default to the website root instead of the application root (~/)? Seems like the latter supports both scenarios and does not introduce any unnecessary coupling between the UI app and the hosting application.

@domaindrivendev
Copy link
Owner

The first thing to note, if you haven't already, is that the semantics (and package name) have changed quite a bit in the most recent release - Swashbuckle.AspNetCore.1.0.0-rc1. Now, you're REQUIRED to specify one or more SwaggerEndpoints when enabling the swagger-ui middleware:

app.UseSwaggerUi(c =>
{
    c.SwaggerEndpoint("/swagger/v1/swagger.json", "My API V1");
})

It's worth noting that the first argument is a URL and not a "route". The value is passed down to the swagger-ui JavaScript client and used by that client to access Swagger JSON. It can be fully qualified or relative to the swagger-ui page.

"Application root" is a .NET, server-side concept and wouldn't make sense on a client. I could change this to accept a "route" instead and have the middleware construct the URL before passing down to the client. But then I'm introducing unwanted coupling between the Swagger JSON and SwaggerUi middleware - namely that they're always on the same host and same virtual directory.

I want to avoid this but I also want to optimize for the more common case - i.e. when they are part of the same app. So, I do have one idea that might achieve this. Consider the following configuration:

// By default - UseSwagger exposes Swagger JSON at /swagger/v1/swagger.json
app.UseSwagger();

// By default - UseSwaggerUi exposes swagger-ui page at /swagger/index.html
app.UseSwaggerUi(c =>
{
    c.SwaggerEndpoint("../v1/swagger.json", "My API V1");
})

As I mentioned, the argument to SwaggerEndpoint can be fully-qualified or relative to the current page. So, you could provide a value that is relative to "swagger/index.html" and agnostic of virtual directories as shown above. This actually works and I believe it will solve your problem. However, it has the downside of displaying your Swagger JSON URL in the UI as follows:

swagger/index.html/../v1/swagger.json

Not ideal but it could be fixed by updating SB to serve the UI page at "/swagger/" instead of "swagger/index.html". This would be cleaner anyway and it would also allow Swagger endpoints to be expressed relative to the swagger-ui page in a way that' agnostic of virtual directories. But, it would be a significant breaking change. Let me know if this makes sense - I'd be interested to get your thoughts ...

@domaindrivendev
Copy link
Owner

This change is now committed to master - 36c25c9. Check out the preview package on myget - https://www.myget.org/feed/domaindrivendev/package/nuget/Swashbuckle.AspNetCore/1.0.0-preview-0101

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants