mirror of
https://github.com/dotnet/intro-to-dotnet-web-dev.git
synced 2025-12-06 05:32:03 +01:00
Update README.md for .NET 9 compatibility and enhanced OpenAPI documentation
This commit is contained in:
parent
5b019a7498
commit
b8955df40b
|
|
@ -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. We’ve 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. It’s a neat, simple format for packaging up data, but programmers don’t 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 shouldn’t 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
|
||||
|
||||
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`:
|
||||
|
||||
```bash
|
||||
dotnet new web -o PizzaStore -f net6.0
|
||||
dotnet new web -o PizzaStore -f net9.0
|
||||
```
|
||||
|
||||
You should see the _PizzaStore_ directory.
|
||||
|
|
@ -88,35 +88,42 @@ 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.
|
||||
|
||||
1. Install the *Swashbuckle* package:
|
||||
|
||||
```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:
|
||||
1. In .NET 9, Swagger support is built in for minimal APIs! Update your _Program.cs_ file with the following code:
|
||||
|
||||
```csharp
|
||||
using Microsoft.OpenApi.Models;
|
||||
|
||||
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.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();
|
||||
|
||||
// Configure the HTTP request pipeline
|
||||
if (app.Environment.IsDevelopment())
|
||||
{
|
||||
app.UseDeveloperExceptionPage();
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c => // UseSwaggerUI Protected by if (env.IsDevelopment())
|
||||
{
|
||||
c.SwaggerEndpoint("/swagger/v1/swagger.json", "PizzaStore API V1");
|
||||
});
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(options =>
|
||||
{
|
||||
options.SwaggerEndpoint("/swagger/v1/swagger.json", "v1");
|
||||
options.RoutePrefix = "swagger";
|
||||
});
|
||||
}
|
||||
|
||||
app.MapGet("/", () => "Hello World!");
|
||||
|
|
@ -124,11 +131,11 @@ Use Swagger to ensure that you have a self-documenting API, where the docs chang
|
|||
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.
|
||||
- The two `builder.Services.Add` lines add the two services that *Swashbuckle* needs to generate the documentation.
|
||||
- The `UseSwagger` and `UseSwaggerUI` lines add the Swagger and Swagger UI endpoints. UseSwaggerUI is called only in development.
|
||||
- Adds the `AddEndpointsApiExplorer` service which is required for Swagger to discover and generate documentation for your API endpoints
|
||||
- Adds the `AddSwaggerGen` service to generate the OpenAPI specification for your API
|
||||
- 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`.
|
||||
|
||||
|
|
@ -217,14 +224,56 @@ Now, connect data in your API.
|
|||
1. Just before `app.Run()`, add the following code:
|
||||
|
||||
```csharp
|
||||
app.MapGet("/pizzas/{id}", (int id) => PizzaDB.GetPizza(id));
|
||||
app.MapGet("/pizzas", () => PizzaDB.GetPizzas());
|
||||
app.MapPost("/pizzas", (Pizza pizza) => PizzaDB.CreatePizza(pizza));
|
||||
app.MapPut("/pizzas", (Pizza pizza) => PizzaDB.UpdatePizza(pizza));
|
||||
app.MapDelete("/pizzas/{id}", (int id) => PizzaDB.RemovePizza(id));
|
||||
// Define API endpoints with OpenAPI descriptions
|
||||
var pizzas = app.MapGroup("/pizzas")
|
||||
.WithTags("Pizzas")
|
||||
.WithOpenApi();
|
||||
|
||||
// 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`:
|
||||
|
||||
|
|
@ -232,17 +281,21 @@ Now, connect data in your API.
|
|||
dotnet run
|
||||
```
|
||||
|
||||
1. In your browser, go to `http://localhost:{PORT}/swagger`.
|
||||
|
||||
You should see the following page rendering:
|
||||
1. In your browser, go to `http://localhost:{PORT}/swagger`. You should see the following page rendering:
|
||||
|
||||

|
||||
|
||||
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?
|
||||
|
||||
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!
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue