Skip to main content

JSON API

In addition to server-rendered HTML pages, our application provides a RESTful JSON API. This is useful for building mobile apps or single-page applications (SPAs) that need to interact with the same data.

Movie endpoints

The API endpoints use the same database logic as the web handlers but return JSON responses instead of HTML.

Fetches a list of movies. We use jsonEncode to convert the model list to a JSON string.

final movies = await database.dataSource
.query<$Movie>()
.withRelation('genre')
.orderBy('createdAt', descending: true)
.get();

return _json({'movies': movies.map(_movieViewModel).toList()});

Movie API contract (summary)

EndpointSuccessCommon failures
GET /api/movies200
GET /api/movies/:id200404 when not found
POST /api/movies201400 validation / malformed JSON
PATCH /api/movies/:id200400 invalid payload, 404 missing
DELETE /api/movies/:id200404 missing

Genre endpoints

final genres = await database.dataSource
.query<$Genre>()
.orderBy('name')
.get();
return _json({'genres': genres.map(_genreViewModel).toList()});

Error Shape

Handlers in this tutorial return explicit JSON for failure modes. Typical responses are:

  • {"error": "Movie not found"} for missing records
  • {"errors": [...]} for validation failures

Payload Format

All API payloads use the field names defined in your models. For example, when creating a movie, the JSON should look like this:

{
"title": "Inception",
"releaseYear": 2010,
"summary": "A thief who steals corporate secrets through the use of dream-sharing technology.",
"genreId": 1
}

Quick Manual Check

curl -s http://localhost:8080/api/movies | jq
curl -s http://localhost:8080/api/genres | jq