In the last lesson, the Kladde got its first endpoint: GET /api/contacts. But an API that can only read is just half the job. In
this lesson, you learn how ASP.NET Core assigns a request to the right endpoint, how values from the address, the headers and the body
get into your parameters, and how an endpoint responds with the fitting status code. In the end, the Kladde can create, read, change
and delete contacts, and every status code is backed up by a test and by curl -i.
Route templates
The first parameter of MapGet is a route template. It consists of segments between slashes. A segment is either fixed text or a
parameter in curly braces:
| Template | matches | doesn’t match |
|---|---|---|
/api/contacts |
/api/contacts, /API/Contacts, /api/contacts/ |
/api/contact |
/api/contacts/{id} |
/api/contacts/7, /api/contacts/abc |
/api/contacts, /api/contacts/7/x |
/api/contacts/{id:int} |
/api/contacts/7, /api/contacts/-3 |
/api/contacts/abc |
/api/reports/{year:int}/{month:int:range(1,12)} |
/api/reports/2024/3 |
/api/reports/2024/13 |
/api/search/{term?} |
/api/search, /api/search/feld |
/api/search/feld/more |
/api/list/{page=1} |
/api/list (page 1), /api/list/4 |
|
/files/{*path} |
/files/a, /files/a/b/c.txt |
After the colon comes a constraint. The most important ones are int, long, guid, bool, min(…), max(…), range(…,…),
length(…) and alpha; you attach several with further colons. A ? makes a parameter optional, an = gives it a default value, and
{*path} catches the whole rest of the address.
A constraint decides whether the route matches. If it doesn’t, there’s simply no endpoint for this address, and the response is
404. A rule follows from that which Microsoft’s documentation names expressly: Constraints are not input validation. They help
tell similar routes apart, for example /api/contacts/{id:int} next to /api/contacts/{slug}. Whether a value is valid in terms of
the business is checked by the endpoint or the model, which then answers with 400 and a reason (lesson 2.3.8). For numbers,
{id:int} is still right: An address like /api/contacts/abc doesn’t designate a contact, and “there’s no such thing” is the honest
answer.