ASP.NET Minimal APIs
A minimal API is a small, fast way to build an API in ASP.NET Core, with very little code.
What is a Web API?
A web API answers requests with data (usually JSON) instead of HTML pages. Mobile apps, React websites and other programs call APIs to get and save data.
HTTP Methods
| Method | Map with | Used to |
|---|---|---|
| GET | app.MapGet | Read data |
| POST | app.MapPost | Create new data |
| PUT | app.MapPut | Update existing data |
| DELETE | app.MapDelete | Remove data |
Returning JSON
Create an empty project with dotnet new web -o ShopApi, then write this in Program.cs:
Example
var builder = WebApplication.CreateBuilder(args);
var app = builder.Build();
var products = new List<Product>
{
new(1, "Rice 5kg", 1650),
new(2, "Cooking Oil 1L", 620),
};
app.MapGet("/products", () => products);
app.Run();
record Product(int Id, string Name, decimal Price);Opening /products returns:
[{"id":1,"name":"Rice 5kg","price":1650},{"id":2,"name":"Cooking Oil 1L","price":620}]ASP.NET Core turns C# objects into JSON automatically. A record is a short way to define a class that only holds data.
Route Parameters and Results
Example
app.MapGet("/products/{id:int}", (int id) =>
{
var product = products.FirstOrDefault(p => p.Id == id);
return product is null ? Results.NotFound() : Results.Ok(product);
});/products/2 returns the product as JSON with status 200. /products/99 returns status 404.
| Result | Status code | Meaning |
|---|---|---|
Results.Ok(x) | 200 | Success, with data |
Results.Created(url, x) | 201 | New item created |
Results.NoContent() | 204 | Success, no data to return |
Results.BadRequest() | 400 | The request data is wrong |
Results.NotFound() | 404 | Item does not exist |
Creating Data with POST
The JSON in the request body is turned into a C# object for you:
Example
app.MapPost("/products", (Product input) =>
{
if (string.IsNullOrWhiteSpace(input.Name) || input.Price <= 0)
{
return Results.BadRequest("Name and a positive price are required.");
}
var created = input with { Id = products.Max(p => p.Id) + 1 };
products.Add(created);
return Results.Created($"/products/{created.Id}", created);
});Test it from a terminal:
Example
curl -X POST http://localhost:5123/products -H "Content-Type: application/json" -d "{\"name\":\"Sugar 1kg\",\"price\":160}"{"id":3,"name":"Sugar 1kg","price":160}Use your own port number. Tools like Postman make testing APIs easier.
Update and Delete
Example
app.MapPut("/products/{id:int}", (int id, Product input) =>
{
var index = products.FindIndex(p => p.Id == id);
if (index == -1) return Results.NotFound();
products[index] = input with { Id = id };
return Results.NoContent();
});
app.MapDelete("/products/{id:int}", (int id) =>
{
var removed = products.RemoveAll(p => p.Id == id);
return removed > 0 ? Results.NoContent() : Results.NotFound();
});Grouping Routes
When many endpoints share a prefix, group them:
Example
var api = app.MapGroup("/api/products");
api.MapGet("/", () => products);
api.MapGet("/{id:int}", (int id) => products.FirstOrDefault(p => p.Id == id));The list in these examples lives in memory, so it resets every time the app restarts. The next lesson saves data in a real database.
Exercise
Exercise
Which method maps an endpoint that creates new data?
