RESTful Blog API with Express
Build a REST API for a blogging platform in TypeScript with Express, Prisma and PostgreSQL: authors write posts, posts have tags and comments, and readers browse posts with filters and pagination. Every request body and query is validated with Zod, and the types flow from the database schema (through Prisma) and the validation schemas (through Zod) all the way to the route handlers, so many mistakes are caught before the code runs. Only a post's author can edit or delete it. The whole API is covered by integration tests with Supertest against a real test database. You'll learn typed Express handlers, Prisma schemas, migrations and relations, validation middleware, pagination and filtering, consistent error handling, and integration testing.
- Estimate
- ~10.5h
- Steps
- 6
- Completed by
- 0
- Proposed by
- codeseed.app
Express · Prisma · PostgreSQL · Zod
Project roadmap
- 01
Set up the project
~1.5hCreate a TypeScript project with Express, Prisma, Zod and tsx for development. Run PostgreSQL with Docker, initialize Prisma, and add a GET /health route. Configure strict TypeScript. Done when: the server starts, connects to the database, and /health returns 200.
- 02
Define the Prisma schema
~1.5hModel Author (name and email unique), Post (title, slug unique, body, published flag, dates and author), Tag (name unique) with a many-to-many relation to posts, and Comment (post, author name, body and date). Create the migration and a seed script with sample data. Done when: prisma migrate dev creates the tables, and the seed script fills them.
- 03
Build the CRUD routes
~2.5hBuild routes for posts (list, get by slug, create, update and delete) and comments (list for a post, add and delete), with typed request and response shapes. Generate slugs from titles, unique per post. Identify the current author with a simple API key header for now, and only let a post's author update or delete it (403 otherwise). Return 201, 204, 404 and 409 correctly. Done when: all routes work with curl.
- 04
Validate input
~1.5hWrite Zod schemas for every body and query string, and a generic middleware that validates and gives handlers the parsed, typed data. Return 400 with a list of field errors, and handle Prisma's known errors (such as a unique constraint) in one error handler that turns them into 409 or 404, never leaking internal details. Done when: invalid requests get clear 400 errors, and handlers only see valid, typed data.
- 05
Add pagination and filters
~1.5hSupport GET /posts?tag=&author=&q=&published=&page=&pageSize= (with a maximum page size), returning items with the total count, and sort by date. Include each post's author name, tags and comment count in one query (using include and _count) instead of one query per post. Done when: filters combine correctly, and listing posts runs a small, fixed number of queries.
- 06
Write integration tests
~2hWrite tests with Vitest (or Jest) and Supertest against a separate test database that is reset before each test file: creating and fetching posts with tags, slugs, permissions, validation errors, comments, filters and pagination, and 404s. Done when: the test suite passes.
Resources
- DocsPrisma documentation
- DocsPrisma: relations
- DocsExpress: routing
- DocsZod documentation
- Docssupertest
Ready to build this?
Get a GitHub repo and start building. Your AI reviewer checks each step as you go.
Tech stack