How to use OpenAPI in ASP.NET Core
By FoxLearn 12/31/2024 6:27:02 AM 113
This is especially useful when working with minimal APIs introduced in ASP.NET Core 6, which simplifies the creation of lightweight APIs by reducing boilerplate code.
What is OpenAPI?
The OpenAPI specification, formerly known as Swagger, is a standardized, machine-readable language-independent format for describing HTTP APIs. It serves as an interface description language (IDL) that is agnostic to programming languages.
- Defining endpoint information.
- Formatting this data in a way that adheres to OpenAPI standards.
- Exposing the OpenAPI schema through either a graphical interface (like Swagger UI) or a serialized file.
In ASP.NET Core 7, the Swashbuckle.AspNetCore package is included by default in Web API projects, providing tools for automatic Swagger documentation.
Creating a Minimal API with OpenAPI Documentation
To create a simple minimal API endpoint in ASP.NET Core, the default setup generates an HTTP GET endpoint in the Program.cs
file.
app.MapGet("/", () => "Hello World!") .WithName("Welcome") .WithOpenApi();
When the app runs, Swagger UI will display this endpoint. You can configure Swagger using the following code:
builder.Services.AddSwaggerGen(setup => setup.SwaggerDoc("v1", new OpenApiInfo() { Description = "Minimal API Demo", Title = "API Example", Version = "v1", Contact = new OpenApiContact() { Name = "Developer Name", Url = new Uri("https://developerwebsite.com") } }));
This metadata will appear in the Swagger UI, providing more details about the API.
Adding a Model and Repository
To extend the minimal API example, let's create a model and an interface for managing data. Here's an example of a Book
model and a corresponding repository interface:
public class Book { public int Id { get; set; } public string Title { get; set; } public string Author { get; set; } public string ISBN { get; set; } }
Next, define the repository interface:
public interface IBookRepository { Book GetById(int id); void Create(Book book); void Update(Book book); void Delete(Book book); }
A skeleton BookRepository
class can implement this interface:
public class BookRepository : IBookRepository { public void Create(Book book) { throw new NotImplementedException(); } public void Delete(Book book) { throw new NotImplementedException(); } public Book GetById(int id) { throw new NotImplementedException(); } public void Update(Book book) { throw new NotImplementedException(); } }
Creating Endpoints
Now, define the minimal API endpoints for managing books in Program.cs
. The following endpoints represent common CRUD operations:
app.MapGet("/books/{id}", async ([FromServices] IBookRepository repo, int id) => { var book = repo.GetById(id); return book != null ? Results.Ok(book) : Results.NotFound(); }); app.MapPost("/books", async ([FromServices] IBookRepository repo, Book book) => { repo.Create(book); return Results.Created($"/books/{book.Id}", book); }); app.MapPut("/books/{id}", async ([FromServices] IBookRepository repo, int id, Book bookToUpdate) => { var existingBook = repo.GetById(id); if (existingBook == null) return Results.NotFound(); repo.Update(bookToUpdate); return Results.Ok(bookToUpdate); }); app.MapDelete("/books/{id}", async ([FromServices] IBookRepository repo, int id) => { var book = repo.GetById(id); if (book == null) return Results.NotFound(); repo.Delete(book); return Results.NoContent(); });
These endpoints will be displayed in the Swagger UI, allowing developers to interact with the API directly through the browser.
Complete Example Code
Here is the complete code for a minimal API with OpenAPI documentation:
using Microsoft.AspNetCore.Mvc; using Microsoft.OpenApi.Models; var builder = WebApplication.CreateBuilder(args); builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); builder.Services.AddSwaggerGen(setup => setup.SwaggerDoc("v1", new OpenApiInfo() { Description = "Minimal API Demo", Title = "API Example", Version = "v1", Contact = new OpenApiContact() { Name = "Developer Name", Url = new Uri("https://developerwebsite.com") } })); var app = builder.Build(); if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } app.UseHttpsRedirection(); app.MapGet("/books/{id}", async ([FromServices] IBookRepository repo, int id) => { var book = repo.GetById(id); return book != null ? Results.Ok(book) : Results.NotFound(); }); app.MapPost("/books", async ([FromServices] IBookRepository repo, Book book) => { repo.Create(book); return Results.Created($"/books/{book.Id}", book); }); app.MapPut("/books/{id}", async ([FromServices] IBookRepository repo, int id, Book bookToUpdate) => { var existingBook = repo.GetById(id); if (existingBook == null) return Results.NotFound(); repo.Update(bookToUpdate); return Results.Ok(bookToUpdate); }); app.MapDelete("/books/{id}", async ([FromServices] IBookRepository repo, int id) => { var book = repo.GetById(id); if (book == null) return Results.NotFound(); repo.Delete(book); return Results.NoContent(); }); app.Run(); public class Book { public int Id { get; set; } public string Title { get; set; } public string Author { get; set; } public string ISBN { get; set; } } public interface IBookRepository { Book GetById(int id); void Create(Book book); void Update(Book book); void Delete(Book book); } public class BookRepository : IBookRepository { public void Create(Book book) { throw new NotImplementedException(); } public void Delete(Book book) { throw new NotImplementedException(); } public Book GetById(int id) { throw new NotImplementedException(); } public void Update(Book book) { throw new NotImplementedException(); } }
ASP.NET Core provides a powerful, built-in OpenAPI integration for documenting minimal APIs. By enabling OpenAPI support when creating a project, you can automatically generate API documentation and explore it via Swagger UI.
- Content Negotiation in Web API
- How to fix 'InvalidOperationException: Scheme already exists: Bearer'
- How to fix System.InvalidOperationException: Scheme already exists: Identity.Application
- Add Thread ID to the Log File using Serilog
- Handling Exceptions in .NET Core API with Middleware
- InProcess Hosting in ASP.NET Core
- Limits on ThreadPool.SetMinThreads and SetMaxThreads
- Controlling DateTime Format in JSON Output with JsonSerializerOptions