Brent Arias
Brent Arias

Reputation: 30215

Listing API Methods Under Multiple Groups

I have Swashbuckle annotated code that looks like this:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
public class AddressesController : Controller
{
    [HttpGet("{aid}")]
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(PostalRecord))]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
       //do something
    }

I would like to use the GroupActionsBy customization, as shown in this example, but I want to have the above GetAddress method simultaneously included into two separate groups that correspond to the two route prefixes shown:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]

In other words, I want the same method to be listed under both:

How can this be done?

Incidentally, I'm working with ASP.NET Core (dnx46). If it is not yet possible to do this with the ASP.NET Core version of Swashbucklee, then a full-CLR (Web API 2.2?) example would still be appreciated.

Also, for a more complete story of what I'm trying to do - I have a separate SO post.

Update

The answer given by @venerik got me close to the solution. When I apply his sample code...

[SwaggerOperation(Tags = new []{"Subscribers", "Organizations"})]

...this causes the Swagger listings to look like this:

enter image description here

In short, the "Addresses" endpoints are now appearing under the headings that I want but, as the red arrow indicates, they are now also being "cross-listed"; I don't want the "Subscribers" endpoint being listed under the "Organizations" endpoint.

I'm suspicious that a [SwaggerOperationFilter] might be "the other half" of the answer, if I can make it remove the cross-listed entries. I've not played with that mechanism before.

Angst

Also, it is very unfortunate that [SwaggerOperation] can only be applied on methods/actions. I would rather apply it to the class itself:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
[SwaggerOperation(Tags = new []{"Subscribers", "Organizations"})]
public class AddressesController : Controller
{

Is there any remedy for this?

Upvotes: 6

Views: 15204

Answers (2)

Brent Arias
Brent Arias

Reputation: 30215

@venerik got me on the right path. But instead of a [SwaggerOperation] attribute, what I needed was a [SwaggerOperationFilter], like this:

public class CategorizeFilter : IOperationFilter
{
    public void Apply(Operation operation, OperationFilterContext context)
    {
        string path = context.ApiDescription.RelativePath;
        string segment = path.Split('/')[1];

        if (segment != context.ApiDescription.GroupName)
        {
            operation.Tags = new List<string> { segment };
        }
    }
}

Then I just decorate my actions as needed:

[Route("api/Subscribers/{id}/[controller]")]
[Route("api/Organizations/{id}/[controller]")]
public class AddressesController : Controller
{
    [HttpGet("{aid}")]
    [SwaggerOperationFilter(typeof(CategorizeFilter))]
    [SwaggerResponse(HttpStatusCode.OK, Type = typeof(PostalRecord))]
    public async Task<IActionResult> GetAddress(Guid id, Guid aid)
    {
       //do something
    }

As a consequence, the "Addresses" category completely disappeared from my Swagger UI (good!) and the twin set of endpoint routes are properly divided between "Organizations" and "Subscribers" groups. Perfect!

Upvotes: 6

venerik
venerik

Reputation: 5904

I do not have experience with ASP.NET Core (yet) but in ASP.NET Web API you can achieve this with the SwaggerOperationAttribute. You can use this attribute to add tags to operations. For instance, the next piece of code adds the tags Subscribers and Organizations:

[SwaggerOperation(Tags = new []{"Subscribers", "Organizations"})]
public async Task<IActionResult> GetAddress(Guid id, Guid aid)
{
   //do something
}

Swagger-UI groups operations by tag, so, GetAddress will get listed under both Subscribers and Organizations.

Upvotes: 10

Related Questions