REST API with Swagger is the de facto standard for shipping a documented HTTP API, and ASP.NET Core 10 makes the entire setup fit in a few lines of Program.cs. Swagger UI is the interactive page your consumers actually use: every endpoint listed, every request and response model described, and every operation testable in the browser. It is all generated from the OpenAPI document your application produces at runtime, which means the documentation and the code can never drift apart.
Without documentation, an API is a black box. Consumers guess at parameter names, discover validation rules by trial and error, and email the team with questions a good docs page would answer instantly. A REST API with Swagger eliminates that friction. Swashbuckle — the .NET implementation of Swagger — reads your routes, your models, and your XML comments, and assembles a complete OpenAPI 3.1 document that Swagger UI renders for humans and that tools can consume for code generation.
In this guide you will build a production-ready REST API with Swagger on .NET 10 from scratch: package setup, SwaggerDoc registration, XML comments, and Swagger UI customization. The examples are deliberately small so you can drop them into a minimal API project immediately.
REST API with Swagger: Adding Swashbuckle to Program.cs
Start by adding the Swashbuckle.AspNetCore NuGet package to your project. Two registrations do the heavy lifting: AddEndpointsApiExplorer, which discovers your minimal API routes, and AddSwaggerGen, which tells Swashbuckle how to build the OpenAPI document. The middleware pair UseSwagger and UseSwaggerUI then serve the raw JSON and the interactive page.
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(options =>
{
options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "Order Service API",
Version = "v1",
Description = "A REST API with Swagger for the Indotalent order service."
});
});
var app = builder.Build();
app.UseSwagger();
app.UseSwaggerUI(options =>
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Order Service v1"));
app.MapGet("/api/health", () => Results.Ok(new { status = "healthy" }));
app.Run();
AddEndpointsApiExplorer registers the API explorer that discovers each MapGet, MapPost, and MapDelete in your application and feeds the metadata to SwaggerGen. SwaggerDoc creates a named document — v1 in this case — and gives you a single place to set the title, version, and description that appear at the top of Swagger UI. Swashbuckle automatically includes your endpoints, your models, and the OpenAPI schema for every DTO they reference.
REST API with Swagger: XML Comments for Self-Documenting Endpoints
A REST API with Swagger that stops at SwaggerDoc shows endpoints and models, but it stays silent about what each endpoint actually does. XML comments change that. Enable documentation file generation in your project file, then document every endpoint with standard triple-slash tags. Swashbuckle reads them and renders summaries, parameter descriptions, and response codes in Swagger UI.
<PropertyGroup>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>$(NoWarn);1591</NoWarn>
</PropertyGroup>
The NoWarn entry suppresses the compiler warning that fires when public members are undocumented. With that in place, annotate each endpoint:
/// <summary>Returns a single order by its identifier.</summary>
/// <param name="id">The order identifier.</param>
/// <response code="200">The requested order.</response>
/// <response code="404">No order matches the identifier.</response>
app.MapGet("/api/orders/{id}", async (Guid id, AppDbContext db) =>
await db.Orders.FindAsync(id) is Order order
? Results.Ok(order)
: Results.NotFound())
.WithName("GetOrder");
Each summary shows up in Swagger UI beside the operation. The response tags become the status codes and schemas consumers see, and the param tags describe the route and query parameters. Combined with the DTOs the endpoint returns, this turns an ordinary route into documentation a teammate could implement against without reading your source code.
REST API with Swagger: Customizing the Swagger UI
Swashbuckle gives you a lot of control over the rendered page. The options below are the ones that matter most for a real team: expanding all endpoints by default, showing request duration, and enabling the filter box that lets consumers search hundreds of operations.
app.UseSwaggerUI(options =>
{
options.SwaggerEndpoint("/swagger/v1/swagger.json", "Order Service v1");
options.DocExpansion(DocExpansion.List);
options.DisplayRequestDuration();
options.EnableFilter();
});
DocExpansion.List renders every operation expanded so consumers see request and response details immediately. DisplayRequestDuration adds a timing readout to each executed call, and EnableFilter adds a search box that filters operations by name or tag. You can also inject custom CSS and JavaScript through InjectStylesheet and InjectJavascript if you want the page to match your brand.
Beyond the visual options, remember that Swashbuckle serves the raw document at the SwaggerEndpoint path. That JSON is what tools like NSwag and OpenAPI Generator consume to produce clients, so keeping it clean is part of good API hygiene. A small habit that pays off is registering a schema filter that sorts properties and trims empty entries from the generated JSON — the document becomes easier for both humans and machines to scan, and the client code it produces reads like a hand-written contract.
REST API with Swagger: Production Configuration
Documentation is most useful exactly where security teams get nervous — production. A few safeguards keep the benefits without the risk: gate Swagger UI behind authentication, serve the OpenAPI JSON from a controlled route, and let developers disable the whole thing with a single environment flag.
if (app.Environment.IsEnvironment("Staging") || app.Environment.IsDevelopment())
{
app.UseSwagger();
app.UseSwaggerUI();
}
Every Indotalent product ships a REST API with Swagger configured exactly this way, so the documentation you see in the store is the same setup you can study in the source code. A third option that keeps the API reachable while the UI stays private is to place UseSwaggerUI after an authorization check in the middleware pipeline — because Swagger UI is just middleware, it can sit behind a custom rule that lets support teams debug internal endpoints without making the page world-readable. From here, the natural next step is adding an Authorize button backed by JWT bearer tokens and enabling versioned documents, which the follow-up articles below cover in detail.
Key Takeaways
- Swagger UI is generated from an OpenAPI document produced at runtime, so documentation can never drift from code
- AddEndpointsApiExplorer and AddSwaggerGen are the complete setup for a minimal API REST API with Swagger
- XML comments convert bare endpoints into rich, readable documentation
- UseSwaggerUI options control how consumers search, expand, and test your API
- Every Indotalent product ships a documented REST API — complete .NET 10 source code for $21 each
FAQ
Is Swagger free to use in .NET 10?
Yes. Swashbuckle.AspNetCore is an open source library maintained by the ASP.NET Core community and distributed through NuGet at no cost.
What is the difference between Swagger and OpenAPI?
OpenAPI is the specification that describes an HTTP API in machine-readable JSON or YAML. Swagger is the tooling that renders that specification — Swagger UI, Swagger Editor, and the Swashbuckle library.
Do minimal APIs support Swagger without controllers?
Completely. AddEndpointsApiExplorer discovers minimal API routes and feeds them to Swashbuckle, so you get the same documentation quality without writing a single controller.
Can I expose Swagger in production?
Yes. Gate it behind authentication, restrict it to non-production environments, or serve it on an internal endpoint. The OpenAPI JSON itself is safe to expose publicly — many teams do.