Core API w/Swagger - Definition by Version and Group/Attribute/Tag

2.3k Views Asked by At

I'm attempting to organize my swagger documentation and I've hit a road block. Versioning is very important but I would like to also organize by an attribute/group name or some other code so that I can end up with multiple API definitions organized by both.

The versioning code is simple:

foreach (var description in provider.ApiVersionDescriptions)
{
     options.SwaggerEndpoint($"/swagger/{description.GroupName}/swagger.json", description.GroupName.ToUpperInvariant());
}

Ideally, it would be something similar to the following:

foreach (var tag in some_variable_that_contains_tags_or_something)
{
     foreach (var description in provider.ApiVersionDescriptions)
     {
         options.SwaggerEndpoint($"/swagger/{tag}/{description.GroupName}/swagger.json", tag + " " + description.GroupName.ToUpperInvariant());
     }
}

Which would be driven by something on the controller like :

[ApiController]
[Tag("Tag Example")] -- Will drive the tag/attribute/something list when creating definitions
[ApiVersion("1.0")]
[EnableCors("CorsPolicy")]
[Route("sample/v{version:apiVersion}")]
public class SampleController : ControllerBase

Any help that anyone could provide would be much appreciated!

1

There are 1 best solutions below

2
Chris Martinez On

What you are trying to achieve is technically possible, but the OpenAPI (formerly Swagger) UI doesn't intrinsically support this behavior. The UI is driven by a single dropdown. This limitation means that you can only partition on a single dimension. Once you add API Versioning, the grouping naturally becomes by API version. The most pragmatic solution you have without changing a bunch of things is to merge both dimensions such that you would have Tag1-V1, Tag2-V1, Tag1-V2, Tage2-V2, and so on. If you're willing to provide your own UI, then you have a lot more options and flexibility.

It's also worth noting that the API Explorer API only has a single level of organization via ApiDescription.GroupName. OpenAPI document generators such as Swashbuckle and NSwag use this to drive organization and is ultimately how documents are married up to the downdrop. Supporting multiple dimensions would require some additional customization there as well because APIs are bucketized into ApiDescriptionGroup, which only has one level of grouping: ApiDescriptionGroup.GroupName.

I provided a much deeper explanation and solution in 68788850. I would also recommend that you use [ApiExplorerSettings(GroupName = "{Tag}")] as opposed to creating your own attribute. You can certainly use your own attribute if you want to, but it's probably just adding extra, unnecessary work.

I can elaborate further if this does not sufficiently answer your question.