Skip to content
Clean Minimal API
Lean Mean Clean Apps

Five templates, one search box. Everything in the docs is in here, including the bits we hoped you'd skim.

Try one of these

Results say which template they came from, so you won't end up reading about Lambda when you wanted GraphQL. Again.

Endpoints

Every endpoint lives in src/Presentation/Endpoints, one static class per feature. Requests and responses are JSON with camelCase property names, read case-insensitively. Properties with no value are left out of responses. Every endpoint except GET /api/version requires authorization, which only has an effect when authentication is on.

The OpenAPI document at /openapi/v1.json describes all of this too, and Scalar at /scalar lets you call it.

Method Route Returns
GET /api/movies A page of movie summaries
GET /api/movies/{id} A movie with its reviews
GET /api/authors A page of author summaries
GET /api/authors/{id} An author with their reviews
GET /api/reviews A page of reviews
GET /api/reviews/{id} A review
POST /api/reviews The created review, with a Location header
PUT /api/reviews/{id} Nothing, 204 No Content
DELETE /api/reviews/{id} Nothing, 204 No Content
GET /api/version The version

Lists movies ordered by title, one page at a time, optionally only those whose title contains a search term.

Query parameter Type Default Rules
query string none Up to 100 characters. Matches the title, ignoring case
offset integer 0 0 or more
limit integer 10 1 to 50
Terminal window
curl "http://localhost:5032/api/movies?query=global&limit=2"
{
"items": [
{ "id": "30fca414-247a-779e-105a-d81aa2506f58", "title": "Assimilated global infrastructure", "reviewCount": 1, "averageStars": 1 },
{ "id": "c27d6600-79a6-9346-2595-a52b7f07dc3e", "title": "Automated global alliance", "reviewCount": 3, "averageStars": 3.3 }
],
"offset": 0,
"limit": 2,
"totalCount": 2
}

Returns one movie with every review written about it, or 404 when there’s no movie with that id.

Lists authors ordered by last name then first name, one page at a time, optionally only those whose name contains a search term. Takes the same parameters as GET /api/movies. query matches anywhere in the full name, written first name then last name.

{
"items": [
{ "id": "01fa8b58-05d2-abd4-e55c-2633222dd0a5", "firstName": "Jana", "lastName": "Auer", "reviewCount": 10, "averageStars": 2.6 },
{ "id": "1cc2ad51-61c5-63ee-dd6e-15308cfe6e51", "firstName": "Caroline", "lastName": "Bins", "reviewCount": 12, "averageStars": 2.7 }
],
"offset": 0,
"limit": 2,
"totalCount": 15
}

Returns one author with every review they have written, or 404 when there’s no author with that id.

Lists reviews ordered by movie then author, one page at a time, optionally only those of one movie, by one author, or both.

Query parameter Type Default Rules
movieId guid none Only reviews of this movie
authorId guid none Only reviews by this author
offset integer 0 0 or more
limit integer 10 1 to 50
Terminal window
curl "http://localhost:5032/api/reviews?movieId=e159975e-4e6a-1ffd-713e-1eb9d8d4a593&limit=2"
{
"items": [
{ "id": "969cb90c-95ae-9189-1e52-0b38d34a911b", "stars": 4, "reviewedMovie": { "id": "e159975e-4e6a-1ffd-713e-1eb9d8d4a593", "title": "Assimilated disintermediate adapter" }, "reviewAuthor": { "id": "1cc2ad51-61c5-63ee-dd6e-15308cfe6e51", "firstName": "Caroline", "lastName": "Bins" } },
{ "id": "a5ebd747-0408-0a96-1af1-eb5cb93bc814", "stars": 1, "reviewedMovie": { "id": "e159975e-4e6a-1ffd-713e-1eb9d8d4a593", "title": "Assimilated disintermediate adapter" }, "reviewAuthor": { "id": "1cc2ad51-61c5-63ee-dd6e-15308cfe6e51", "firstName": "Caroline", "lastName": "Bins" } }
],
"offset": 0,
"limit": 2,
"totalCount": 6
}

Returns one review, or 404 when there’s no review with that id.

Creates a review. The author and the movie must already exist.

Body property Type Rules
authorId guid Required. An existing author
movieId guid Required. An existing movie
stars integer 1 to 5
Terminal window
curl -X POST "http://localhost:5032/api/reviews" -H "Content-Type: application/json" \
-d '{"authorId":"01fa8b58-05d2-abd4-e55c-2633222dd0a5","movieId":"e159975e-4e6a-1ffd-713e-1eb9d8d4a593","stars":5}'

Answers 201 Created with the new review in the body and its URL in the Location header. An unknown author or movie answers 404.

Changes the star rating of a review. The author and the movie of a review can’t change.

Body property Type Rules
stars integer 1 to 5

Answers 204 No Content, or 404 when there’s no review with that id.

Permanently removes a review. Answers 204 No Content, or 404 when there’s no review with that id.

Returns the version stamped into the build. Never requires a token.

{ "fileVersion": "1.1.0.0", "informationalVersion": "1.1.0.0+044d2922e197f24d9a3f311f87a7e323add1a530" }

Every list endpoint returns one page.

Property Type Description
items array The results on this page
offset integer The offset that was asked for
limit integer The limit that was asked for
totalCount integer The number of results across every page

To read everything, start at offset 0 and add limit to it until offset reaches totalCount.

Property Type Description
id guid The movie’s id
title string The movie’s title
reviewCount integer How many reviews the movie has
averageStars number The average rating to one decimal place. Left out when there are no reviews
Property Type Description
id guid The movie’s id
title string The movie’s title
reviews array of review Every review of the movie
Property Type Description
id guid The author’s id
firstName string The author’s first name
lastName string The author’s last name
reviewCount integer How many reviews the author has written
averageStars number The average rating they give. Left out when there are no reviews
Property Type Description
id guid The author’s id
firstName string The author’s first name
lastName string The author’s last name
reviews array of review Every review by the author
Property Type Description
id guid The review’s id
stars integer The rating, from 1 to 5
reviewedMovie object The movie’s id and title
reviewAuthor object The author’s id, firstName and lastName
Property Type Description
fileVersion string The assembly file version
informationalVersion string The informational version, with the prerelease label and commit hash when there are any

Every error is a Problem Details response with the application/problem+json content type.

Status When Extra properties
400 Bad Request A parameter or body property breaks one of the rules above, or the body isn’t valid JSON errors, a property name to messages map, for validation failures
401 Unauthorized Authentication is on and the token is missing or not valid
404 Not Found The movie, author or review doesn’t exist detail says which
500 Internal Server Error Something unexpected happened
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.1",
"title": "One or more validation errors occurred.",
"status": 400,
"errors": { "Limit": ["A limit must be between 1 and 50."] },
"traceId": "00-4241b018629bd38a0a6d370c3a214e2f-cce80e4f478496c2-00"
}
{
"type": "https://tools.ietf.org/html/rfc9110#section-15.5.5",
"title": "Not Found",
"status": 404,
"detail": "The Movie with the supplied id was not found.",
"traceId": "00-85575ee9ac241f705f634081d3bb7fba-93e062125f418354-00"
}