After setting up Swagger for basic API documentation, I realized there's so much more you can do with it — especially in real-world projects. Grouping endpoints, supporting versioning, securing Swagger with JWT, and even hiding endpoints when needed — these advanced use cases have made my development workflow smoother and more professional.
In this article, I’m sharing the Swagger features I actually use in .NET 6, 7, and 8 projects — along with code snippets, tips, and things to avoid.
📚 1. Grouping Endpoints (Using Tags)
Sometimes your Swagger UI becomes overwhelming with too many endpoints. Grouping them into logical sections makes it easier to navigate.
🔧 Option 1. Group by controller name (default)
This happens automatically, but you can customize it further.
🔧 Option 2. Use [ApiExplorerSettings(GroupName = "v1")]
Or use SwaggerDoc
and define multiple groups.
// Program.cs
builder.Services.AddSwaggerGen(c =>
{
c.SwaggerDoc("v1", new OpenApiInfo { Title = "My API V1", Version = "v1" });
c.SwaggerDoc("v2", new OpenApiInfo { Title = "My API V2", Version = "v2" });
});
// Controller
[ApiExplorerSettings(GroupName = "v2")]
[Route("api/v2/[controller]")]
public class OrdersController : ControllerBase
{
//...
}
Now, Swagger UI will show v1
and v2
as tabs.
🔄 2. API Versioning in Swagger
If your app supports multiple API versions, Swagger should reflect that. Here’s how to set it up.
✅ Step 1. Add required NuGet packages
dotnet add package Microsoft.AspNetCore.Mvc.Versioning
dotnet add package Microsoft.AspNetCore.Mvc.Versioning.ApiExplorer
✅ Step 2. Configure versioning
builder.Services.AddApiVersioning(options =>
{
options.ReportApiVersions = true;
options.AssumeDefaultVersionWhenUnspecified = true;
options.DefaultApiVersion = new ApiVersion(1, 0);
});
builder.Services.AddVersionedApiExplorer(options =>
{
options.GroupNameFormat = "'v'VVV";
options.SubstituteApiVersionInUrl = true;
});
✅ Step 3. Update SwaggerGen
builder.Services.AddSwaggerGen();
builder.Services.ConfigureOptions<ConfigureSwaggerOptions>();
(You’ll need to create a ConfigureSwaggerOptions
class — I can generate this for you if needed.)
🔐 3. Add JWT Authentication to Swagger UI
If you're using JWT Bearer tokens, you can allow Swagger to send them in request headers.
✅ Configure Swagger with Security Definitions
builder.Services.AddSwaggerGen(c =>
{
c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
{
Description = "Enter 'Bearer' followed by your JWT token.",
Name = "Authorization",
In = ParameterLocation.Header,
Type = SecuritySchemeType.ApiKey,
Scheme = "Bearer"
});
c.AddSecurityRequirement(new OpenApiSecurityRequirement
{
{
new OpenApiSecurityScheme
{
Reference = new OpenApiReference
{
Type = ReferenceType.SecurityScheme,
Id = "Bearer"
}
},
Array.Empty<string>()
}
});
});
Now Swagger UI will show an Authorize button at the top where you can paste your token.
🙈 4. Hiding Specific Endpoints from Swagger
Sometimes you don’t want every endpoint exposed in Swagger, especially internal or admin-only APIs.
🔧 Option. Use [ApiExplorerSettings(IgnoreApi = true)]
[ApiExplorerSettings(IgnoreApi = true)]
[HttpGet("internal-only")]
public IActionResult HiddenEndpoint()
{
return Ok("This won't appear in Swagger");
}
Works at both the action and controller level.
📤 5. Export Swagger JSON/YAML
You can share your API contract with clients or import it into tools like Postman or Azure API Management.
-
JSON endpoint:
https://localhost:5001/swagger/v1/swagger.json
-
YAML: You’ll need a separate generator, or use tools like Swagger Editor or SwaggerHub to convert JSON to YAML.
📝 6. Improve Models with DataAnnotations
Swagger auto-generates schemas from your models. Enhance them with [Required]
, [StringLength]
, and summaries.
public class ProductDto
{
[Required]
[StringLength(50)]
public string Name { get; set; }
/// <summary>Product price in USD</summary>
public decimal Price { get; set; }
}
Make sure XML comments are enabled to see them in the UI.
🎨 7. UI Customizations (Logo, Layout, etc.)
You can style Swagger UI by injecting CSS or JS.
app.UseSwaggerUI(c =>
{
c.InjectStylesheet("/swagger-ui/custom.css");
c.DocumentTitle = "My API Docs";
});
Use this to:
- Add your company logo
- Change the default collapsed/expanded state
- Customize font/colors
🚀 Best Practices I Follow
Practice |
Why It Matters |
Group endpoints and support versioning |
Helps clients consume APIs reliably |
Secure Swagger UI with tokens or roles |
Avoids exposing sensitive endpoints |
Use meaningful model annotations |
Improves documentation quality |
Keep Swagger in sync with real behavior |
Prevents confusion for API consumers |
Don’t expose internal/test-only APIs |
Keeps docs clean and production-safe |
👋 Conclusion
When you go beyond the basics, Swagger becomes a powerful tool, not just for docs, but for API governance and developer experience. These advanced use cases have helped me a lot when working with large APIs and teams.
If you’re already using Swagger in your .NET app, I highly recommend trying out a few of these. They’re not hard to implement, and the payoff is worth it.