Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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:

  • Subscribers
  • Organizations

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?

like image 602
Brent Arias Avatar asked Apr 09 '16 23:04

Brent Arias


Video Answer


1 Answers

@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!

like image 171
Brent Arias Avatar answered Oct 29 '22 03:10

Brent Arias