Update README.md for .NET 9 compatibility and enhanced OpenAPI documentation

This commit is contained in:
Jon Galloway 2025-05-12 22:21:52 -07:00
parent 5b019a7498
commit b8955df40b

View file

@ -20,7 +20,7 @@ Because these things are so common, the web was designed with standard commands
To avoid reinventing things over and over, we use some common standards for HTTP APIs. Weve already talked about HTTP, which handles the commands and communication between clients and servers. Another important thing for HTTP APIs to do in a predictable way is to send data back and forth. The most common way to package up data now is called JSON, short for JavaScript Object Notation. Its a neat, simple format for packaging up data, but programmers dont want to spend time converting their information back and forth between properties and classes in their programming language and JSON. This conversion process is called serialization, and fortunately ASP.NET Core can do that for you automatically. To avoid reinventing things over and over, we use some common standards for HTTP APIs. Weve already talked about HTTP, which handles the commands and communication between clients and servers. Another important thing for HTTP APIs to do in a predictable way is to send data back and forth. The most common way to package up data now is called JSON, short for JavaScript Object Notation. Its a neat, simple format for packaging up data, but programmers dont want to spend time converting their information back and forth between properties and classes in their programming language and JSON. This conversion process is called serialization, and fortunately ASP.NET Core can do that for you automatically.
### Welcome to the internet... ### Welcome to the internet
Another important thing to think about for server exposed to the public internet is security and authorization. Some HTTP APIs require authentication, so only clients with the right credentials can access them. Even public HTTP APIs need to handle security, to manage things like denial of service attacks and exploiting the public APIs to take over the server or get access to information they shouldnt have. Fortunately, ASP.NET Core can handle things like this for us, too. Another important thing to think about for server exposed to the public internet is security and authorization. Some HTTP APIs require authentication, so only clients with the right credentials can access them. Even public HTTP APIs need to handle security, to manage things like denial of service attacks and exploiting the public APIs to take over the server or get access to information they shouldnt have. Fortunately, ASP.NET Core can handle things like this for us, too.
@ -47,12 +47,12 @@ This endpoint accepts a pizza JSON object, turns it into C#, and passes it to a
### Create a new Minimal API project ### Create a new Minimal API project
First, you need to scaffold a project. You've installed .NET 6 and you're ready to go. First, you need to scaffold a project. You've installed .NET 9 and you're ready to go.
1. Create a web API by running `dotnet new`: 1. Create a web API by running `dotnet new`:
```bash ```bash
dotnet new web -o PizzaStore -f net6.0 dotnet new web -o PizzaStore -f net9.0
``` ```
You should see the _PizzaStore_ directory. You should see the _PizzaStore_ directory.
@ -88,47 +88,54 @@ Congratulations! You've created an API by using a minimal API template.
Use Swagger to ensure that you have a self-documenting API, where the docs change when you change the code. This also builds a really convenient web interface for your API, so you can test out the application as you build it. Use Swagger to ensure that you have a self-documenting API, where the docs change when you change the code. This also builds a really convenient web interface for your API, so you can test out the application as you build it.
1. Install the *Swashbuckle* package: 1. In .NET 9, Swagger support is built in for minimal APIs! Update your _Program.cs_ file with the following code:
```bash
dotnet add package Swashbuckle.AspNetCore
```
1. Next, configure your project to use Swagger. Open _Program.cs_ and add replace it with the following code:
```csharp ```csharp
using Microsoft.OpenApi.Models; using Microsoft.OpenApi.Models;
var builder = WebApplication.CreateBuilder(args); var builder = WebApplication.CreateBuilder(args);
// Add services to the container
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer(); builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c => builder.Services.AddSwaggerGen(options =>
{ {
c.SwaggerDoc("v1", new OpenApiInfo { Title = "PizzaStore API", Description = "Making the Pizzas you love", Version = "v1" }); options.SwaggerDoc("v1", new OpenApiInfo
{
Title = "PizzaStore API",
Description = "Making the Pizzas you love",
Version = "v1",
Contact = new OpenApiContact
{
Name = "Pizza Support",
Email = "pizza@example.com"
}
});
}); });
var app = builder.Build(); var app = builder.Build();
// Configure the HTTP request pipeline
if (app.Environment.IsDevelopment()) if (app.Environment.IsDevelopment())
{ {
app.UseDeveloperExceptionPage(); app.UseSwagger();
app.UseSwagger(); app.UseSwaggerUI(options =>
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment()) {
{ options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1"); options.RoutePrefix = "swagger";
}); });
} }
app.MapGet("/", () => "Hello World!"); app.MapGet("/", () => "Hello World!");
app.Run(); app.Run();
``` ```
This is actually just adding a few lines of code: This code:
- The `using` statement at the top makes it easier to use the *Swashbuckle* package without having to type out long namespaces for the commands. - Adds the `AddEndpointsApiExplorer` service which is required for Swagger to discover and generate documentation for your API endpoints
- The two `builder.Services.Add` lines add the two services that *Swashbuckle* needs to generate the documentation. - Adds the `AddSwaggerGen` service to generate the OpenAPI specification for your API
- The `UseSwagger` and `UseSwaggerUI` lines add the Swagger and Swagger UI endpoints. UseSwaggerUI is called only in development. - Configures Swagger UI which provides an interactive UI for testing your API endpoints
1. Rerun the project and go to the app's address, `http://localhost:{PORT}/swagger`. 1. Rerun the project and go to the app's address, `http://localhost:{PORT}/swagger`.
@ -217,14 +224,56 @@ Now, connect data in your API.
1. Just before `app.Run()`, add the following code: 1. Just before `app.Run()`, add the following code:
```csharp ```csharp
app.MapGet("/pizzas/{id}", (int id) => PizzaDB.GetPizza(id)); // Define API endpoints with OpenAPI descriptions
app.MapGet("/pizzas", () => PizzaDB.GetPizzas()); var pizzas = app.MapGroup("/pizzas")
app.MapPost("/pizzas", (Pizza pizza) => PizzaDB.CreatePizza(pizza)); .WithTags("Pizzas")
app.MapPut("/pizzas", (Pizza pizza) => PizzaDB.UpdatePizza(pizza)); .WithOpenApi();
app.MapDelete("/pizzas/{id}", (int id) => PizzaDB.RemovePizza(id));
// Get all pizzas
pizzas.MapGet("/", () => PizzaDB.GetPizzas())
.WithName("GetAllPizzas")
.WithSummary("Get all pizzas")
.WithDescription("Retrieves the complete list of available pizzas");
// Get pizza by ID
pizzas.MapGet("/{id}", (int id) => PizzaDB.GetPizza(id))
.WithName("GetPizzaById")
.WithSummary("Get pizza by ID")
.WithDescription("Gets a specific pizza by its unique identifier")
.WithOpenApi(operation => {
operation.Parameters[0].Description = "The unique identifier for the pizza";
return operation;
});
// Create a new pizza
pizzas.MapPost("/", (Pizza pizza) => PizzaDB.CreatePizza(pizza))
.WithName("CreatePizza")
.WithSummary("Create a new pizza")
.WithDescription("Adds a new pizza to the menu");
// Update a pizza
pizzas.MapPut("/", (Pizza pizza) => PizzaDB.UpdatePizza(pizza))
.WithName("UpdatePizza")
.WithSummary("Update an existing pizza")
.WithDescription("Updates the details of an existing pizza");
// Delete a pizza
pizzas.MapDelete("/{id}", (int id) => PizzaDB.RemovePizza(id))
.WithName("DeletePizza")
.WithSummary("Delete a pizza")
.WithDescription("Removes a pizza from the menu")
.WithOpenApi(operation => {
operation.Parameters[0].Description = "The unique identifier for the pizza to delete";
return operation;
});
``` ```
This is the actual API part of the application! As you can see, there's not a lot of code. We're just mapping the routes to code that calls into our in-memory store. This is the actual API part of the application! In .NET 9, we're improving the OpenAPI documentation by:
- Using `.WithTags()` to organize endpoints in the Swagger UI
- Adding `.WithSummary()` and `.WithDescription()` to provide clear documentation
- Using the advanced `.WithOpenApi()` overload to customize parameter descriptions
- Organizing routes with `MapGroup()` for cleaner code
1. Run the app by using `dotnet run`: 1. Run the app by using `dotnet run`:
@ -232,17 +281,21 @@ Now, connect data in your API.
dotnet run dotnet run
``` ```
1. In your browser, go to `http://localhost:{PORT}/swagger`. 1. In your browser, go to `http://localhost:{PORT}/swagger`. You should see the following page rendering:
You should see the following page rendering:
![Swagger](swagger-crud.png) ![Swagger](swagger-crud.png)
What's great about this Swagger UI is that you can use it to test out the API. Click on any of the API endpoints to expand it, and click the `Try it out` button. You'll see a form that makes it easy to try submitting requests to the API and seeing the response. What's great about this Swagger UI is that you can:
- Browse all available endpoints organized by tags
- See detailed documentation including summaries and descriptions
- Expand any endpoint to see request parameters and response types
- Try out the API directly with the "Try it out" button
- Execute requests and see the actual responses without leaving the browser
## What's next? ## What's next?
This is a quick first look at building a backend with Minimal APIs. To go through this same example in more detail, and with more explanation, check out the [Minimal API learning path on Microsoft Learn](https://docs.microsoft.com/learn/paths/aspnet-core-minimal-api/)! This is a quick first look at building a backend with Minimal APIs in .NET 9. To learn more about the latest features in Minimal APIs and OpenAPI support, check out the [.NET 9 minimal API documentation](https://learn.microsoft.com/aspnet/core/fundamentals/minimal-apis) and [OpenAPI documents in ASP.NET Core](https://learn.microsoft.com/aspnet/core/fundamentals/openapi/using-openapi-documents).
In the next lesson, you'll learn about building a game with Blazor! Stay tuned! In the next lesson, you'll learn about building a game with Blazor! Stay tuned!