Build a Typed REST API with Express, TypeScript & Zod

Lesson 8 of 8

Final Project: Build a Typed Task API

Put every piece from this course together into one working, fully typed REST API for managing tasks.

Requirements

  1. Define a TaskSchema with Zod (id, title, done, priority, and at least one more field of your choice), derive Task with z.infer.
  2. Derive CreateTaskSchema (omit id/done) and UpdateTaskSchema (fully partial, id omitted) from TaskSchema, the way the earlier lesson did.
  3. Implement all five endpoints against an in-memory array: GET /tasks, GET /tasks/:id, POST /tasks, PATCH /tasks/:id, DELETE /tasks/:id.
  4. Use the validateBody middleware on POST and PATCH, returning 400 with the flattened Zod error on invalid input.
  5. Use the asyncHandler wrapper on every route, and register a typed errorHandler (four-parameter, err: unknown) after all routes.
  6. Return 404 for GET/PATCH/DELETE on a task id that doesn't exist.

Stretch goals

  • Add a GET /tasks?priority=high filter using a Zod schema to validate the query string too.
  • Add pagination (?page=, ?limit=) with sensible defaults.
  • Split schemas, routes, and the in-memory store into separate files, importing/exporting types and schemas between them.
  • Write a small script (or use a REST client) that sends an intentionally invalid request and confirms you get a 400 with a useful error message back.

Submit your repository link below when you are done, an instructor will review it before you can mark this lesson complete. Good luck! 🚀

This lesson ends in a project. Build it on your own machine, there's nowhere to submit it here, but the brief above is everything you need.