Reputation: 337560
I have setup Swagger/Swashbuckle on my WebAPI project. I have followed the guide from Microsoft which covers how to setup Aspnet.WebApi.Versioning with Swagger. My API has multiple versions, so there is a {version}
parameter set in the route attributes, like this:
[ApiVersion("2")]
[RoutePrefix("api/{version:apiVersion}/values")]
public class AccountController : ApiController
{
[Route("UserInfo")]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
My issue is that this shows a {version}
attribute in the path shown in the docs, like this:
Instead I want this path attribute to actually have the value in the ApiVersion
attribute, so that there can be no confusion for the clients who read the documentation. Ideally, given that the UrlDiscoverySelector is set to v2
the paths above should be:
/api/2/account/userinfo
/api/2/account/externallogin
/api/2/account/manageinfo
My attempts to simply replace the {version}
in the RelativePath
of the ApiExplorer
worked in the UI, but broke the test functionality as {version}
was changed to a query
parameter instead of a path
, which is not how my API is configured.
Is it possible I can amend the values in the ApiExplorer
before swagger builds the documentation while still retaining test functionality?
Upvotes: 1
Views: 3667
Reputation: 4368
The API Explorer for API versioning now supports the behavior out-of-the-box using:
options.SubstituteApiVersionInUrl = true
This will do the substitution work for you and removes the API version parameter from the action descriptor. You generally don't need to change the default format applied to the substituted value, but you can change it using:
options.SubstitutionFormat = "VVV"; // this is the default
Upvotes: 3
Reputation: 1
I'm using a Swashbuckle and used a Document filter
public class VersionedOperationsFilter : IDocumentFilter
{
public void Apply(SwaggerDocument swaggerDoc, DocumentFilterContext context)
{
foreach (var apiDescriptionsGroup in context.ApiDescriptionsGroups.Items)
{
var version = apiDescriptionsGroup.GroupName;
foreach (ApiDescription apiDescription in apiDescriptionsGroup.Items)
{
apiDescription.RelativePath = apiDescription.RelativePath.Replace("{version}", version);
}
}
}
}
and in ConfigureServices method in Startup.cs add this filter:
services.AddMvc();
var defaultApiVer = new ApiVersion(1, 0);
services.AddApiVersioning(option =>
{
option.ReportApiVersions = true;
option.AssumeDefaultVersionWhenUnspecified = true;
option.DefaultApiVersion = defaultApiVer;
});
services.AddMvcCore().AddVersionedApiExplorer(e=>e.DefaultApiVersion = defaultApiVer);
services.AddSwaggerGen(
options =>
{
var provider = services.BuildServiceProvider().GetRequiredService<IApiVersionDescriptionProvider>();
options.DocumentFilter<VersionedOperationsFilter>();
//// add a swagger document for each discovered API version
//// note: you might choose to skip or document deprecated API versions differently
foreach (var description in provider.ApiVersionDescriptions)
{
options.SwaggerDoc(description.GroupName.ToString(),
CreateInfoForApiVersion(description));
}
//// integrate xml comments
options.IncludeXmlComments(Path.ChangeExtension(Assembly.GetEntryAssembly().Location, "xml"));
});
Upvotes: 0