Reputation: 1073
I have an ASP.NET Core 9 Web API application. By default, .NET9 doesn't use Swashbuckle anymore. To generate API documentations I'm using Microsoft OpenAPI documents and Scalar.
It works fine. I need to group all endpoints into smaller groups. For example, User, Order etc. User group will contain authentication controller, changing profile profile controller and Order group will contain order controller and payment controller.
Is it possible to group those endpoints?
Upvotes: 3
Views: 926
Reputation: 504
Use the Tags attribute. I've found Scalar will group the methods under those tags perfectly. Something similar to:
[EndpointDescription("Retrieve a paged list of people based on a set of filters")]
[EndpointSummary("List People")]
[Tags("People")]
[HttpGet("people")]
[ProducesResponseType<PagedResultDto<PersonDto>>(StatusCodes.Status200OK, "application/json")]
public async Task<IActionResult> GetPeople([FromQuery] GetPeopleInputDto inputDto)
{ ... }
Upvotes: 3
Reputation: 21636
What I'm looking for is grouping multiple controllers into a single group name.
You can try to use [ApiExplorerSettings]
attribute and a Swagger operation filter or API conventions to group multiple API controllers under a single group name.
Add [ApiExplorerSettings]
attribute in the controller, code like this:
[Route("api/[controller]")]
[ApiController]
[ApiExplorerSettings(GroupName = "MyGroup")]
public class TodoController : ControllerBase
{
and
[Route("api/[controller]")]
[ApiController]
[ApiExplorerSettings(GroupName = "MyGroup")]
public class ValuesController : ControllerBase
{
then, in the Program.cs file:
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API", Version = "v1" });
c.DocInclusionPredicate((docName, apiDesc) =>
{
if (docName == "MyGroup")
{
return apiDesc.GroupName == "MyGroup";
}
return true;
});
c.TagActionsBy(api => new[] { api.GroupName ?? "Default" });
});
The result as below:
Using Scalar to check the https://localhost:7045/swagger/v1/swagger.json, the result like this:
Upvotes: 0
Reputation: 21636
You can use Swashbuckle.AspNetCore
and Scalar.AspNetCore
together to group the controllers and endpoints.
You can check the following sample:
NET9API.csproj: Installed the Swashbuckle.AspNetCore
and Scalar.AspNetCore
package from NuGet.
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.0" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="9.0.0" />
<PackageReference Include="Scalar.AspNetCore" Version="1.2.44" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.9.0" />
</ItemGroup>
</Project>
Then, in the Program.cs file:
using Scalar.AspNetCore;
using NET9API.Controllers;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
builder.Services.AddControllers();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();
var app = builder.Build();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.MapScalarApiReference();
}
if (app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
};
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();
app.MapUserEndpoints(); //after adding the "API endpoints via API with Read/write endpoints" Scaffold, we can add the maps.
app.Run();
Then, we can use the following options to add controller or endpoints:
In this example, I've added the Values controller and the Users endpoint in the same way as above.
The ValuesController.cs file like this:
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
// GET: api/<ValuesController>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
// GET api/<ValuesController>/5
[HttpGet("{id}")]
public string Get(int id)
{
return "value";
}
// POST api/<ValuesController>
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/<ValuesController>/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/<ValuesController>/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
and the UsersController.cs file as below:
using NET9API.Models;
namespace NET9API.Controllers;
public static class UsersController
{
public static void MapUserEndpoints (this IEndpointRouteBuilder routes)
{
var group = routes.MapGroup("/api/User").WithTags(nameof(User));
group.MapGet("/", () =>
{
return new [] { new User() };
})
.WithName("GetAllUsers")
.WithOpenApi();
group.MapGet("/{id}", (int id) =>
{
//return new User { ID = id };
})
.WithName("GetUserById")
.WithOpenApi();
group.MapPut("/{id}", (int id, User input) =>
{
return TypedResults.NoContent();
})
.WithName("UpdateUser")
.WithOpenApi();
group.MapPost("/", (User model) =>
{
//return TypedResults.Created($"/api/Users/{model.ID}", model);
})
.WithName("CreateUser")
.WithOpenApi();
group.MapDelete("/{id}", (int id) =>
{
//return TypedResults.Ok(new User { ID = id });
})
.WithName("DeleteUser")
.WithOpenApi();
}
}
After running the application, and use Scalar to check the openAPI json file (https://localhost:{port}/openapi/v1.json
), the output as below:
Upvotes: 0