Pebellslearn by building
0%
RoadmapsMatrixCoursesSandboxSign in
ASP.NET Core Basics: Endpoints  ›  Lesson

Minimal APIs — An Endpoint in One Line

Minimal APIs 15 minA Minimal API maps an HTTP method and route straight to a lambda whose parameters are bound from the request and whose return value becomes the response.

Minimal APIs — An Endpoint in One Line

A new ASP.NET Core project does not make you create folders of classes before you can say hello. With Minimal APIs, ReadingRoom's first endpoint is one line in Program.cs. It is the default style of the webapi template, and it scales further than its name suggests.

The rule

Map a method and route to a function; parameters bind in, results go out.

var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSingleton<BookStore>();      // register services
var app = builder.Build();

app.MapGet("/books", (BookStore store) => store.All());

app.MapGet("/books/{id:int}", (int id, BookStore store) =>
    store.Find(id) is Book book
        ? TypedResults.Ok(book)
        : Results.NotFound());

app.MapPost("/books", (Book book, BookStore store) =>
{
    store.Add(book);
    return TypedResults.Created($"/books/{book.Id}", book);
});

app.Run();

MapGet, MapPost, MapPut, MapPatch and MapDelete each pair a method with a route. {id:int} is a route parameter with a constraint: /books/abc never matches.

Binding fills each lambda parameter from the right place:

  • a name that matches a route segment → from the route (id)
  • a simple type not in the route → from the query string (?page=2)
  • a complex type on POST/PUT → from the JSON body (Book book)
  • a registered service → from dependency injection (BookStore store)

Attributes such as [FromQuery] or [FromHeader] override the guess. Whatever you return is written back: an object becomes JSON with 200 OK; Results/TypedResults let you choose the status. app.MapGroup("/books") shares a prefix across related endpoints.

The shortcut

For each parameter, ask "is it in the route, a service, or a body?" — in that order. Anything left that is simple comes from the query string.

Binding a loan requestStep 1 of 4
  1. The endpoint

    app.MapGet("/members/{memberId:int}/loans", (int memberId, bool overdueOnly, LibraryDb db) => ...)

The trap: returning null for a missing book. That sends 200 with an empty body; return Results.NotFound() instead.

Drills

Answer fast — trust the rule.

quick drill

In app.MapGet("/books/{id:int}", (int id) => ...), what does /books/abc get?

quick drill

In a MapPost, where does a Book book parameter come from by default?

quick drill

What does TypedResults.Created("/books/7", book) produce?

quick drill

What does app.MapGroup("/books") help with?

Remember

  • Map a method and route to a function; parameters bind in, results go out.
  • Route, then service, then body; leftover simple values come from the query.
  • Choose the status with Results/TypedResults, never return a bare null.

Practice — level up

0/1 solved

Write your answer, then compare it with a rubric and a model answer.

ExplainWhere does each parameter come from?

Explain how ASP.NET Core fills each parameter of app.MapPost("/members/{memberId:int}/loans", (int memberId, LoanRequest body, LibraryDb db) => ...) and what the lambda should return when the member does not exist and when the loan is created.