Skip to content

obadaDeg/chirpy-api

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

19 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Chirpy API

A RESTful HTTP server built with TypeScript and Express as part of the Boot.dev backend development curriculum.

This is the 3rd project in the 7th course of the Foothill Training plan, covering HTTP server fundamentals through building a Twitter-like microblogging API.

About

Chirpy is a backend API that powers a microblogging platform. Users can register, post short messages ("chirps"), authenticate using JWTs and refresh tokens, and be upgraded to Chirpy Red membership via webhook events. The project covers core HTTP server concepts — routing, middleware, authentication, authorization, and database integration — without any frontend.

Project Progression

Milestone 1 — HTTP Server Basics

  • Express.js server setup with TypeScript and ESM modules
  • Static file serving for the admin dashboard
  • Readiness check endpoint (GET /api/healthz)
  • Admin metrics endpoint to track file server hits

Milestone 2 — Users & Chirps

  • PostgreSQL database with Drizzle ORM
  • User creation with Argon2 password hashing
  • Chirp CRUD (create, read, delete)
  • Profanity filtering on chirp content (kerfuffle, sharbert, fornax****)
  • 140-character chirp length limit

Milestone 3 — Authentication

  • JWT access tokens (1-hour expiry) with jsonwebtoken
  • 60-day refresh tokens stored in the database (cryptographically random hex strings)
  • Login endpoint returning both access and refresh tokens
  • Token refresh (POST /api/refresh) and revocation (POST /api/revoke)
  • authMiddleware using res.locals for safe auth data passing across middleware

Milestone 4 — Authorization

  • Protected routes for creating/deleting chirps and updating user details
  • Ownership enforcement: users can only delete their own chirps
  • User profile updates (email and/or password) behind JWT auth

Milestone 5 — Webhooks & Membership

  • Polka payment webhook (POST /api/polka/webhooks) to upgrade users to Chirpy Red
  • API key authentication for webhook security
  • Idempotent webhook handling (user.upgraded event)
  • isChirpyRed boolean field on the users table

Milestone 6 — Filtering & Sorting

  • Filter chirps by author (?authorId=<uuid>)
  • Sort chirps by creation date (?sort=asc|desc)
  • DB-level filtering for author, in-memory sort for flexibility

Getting Started

Prerequisites

  • Node.js 18+
  • PostgreSQL database (local or cloud)
  • A .env file in the project root (see below)

Environment Variables

DB_URL=postgres://user:password@localhost:5432/chirpy
JWT_SECRET=your-secret-here
POLKA_KEY=your-polka-api-key
PLATFORM=dev

Installation

npm install

Run database migrations:

npx drizzle-kit generate
npx drizzle-kit migrate

Start the server:

npm run dev

Run tests:

npm test

API Reference

Health

Method Endpoint Auth Description
GET /api/healthz None Server readiness check

Users

Method Endpoint Auth Description
POST /api/users None Create a new user
PUT /api/users Bearer JWT Update email and/or password
POST /api/login None Login, returns JWT + refresh token
POST /api/refresh Bearer refresh token Get a new JWT access token
POST /api/revoke Bearer refresh token Revoke a refresh token

POST /api/users

// Request
{ "email": "user@example.com", "password": "hunter2" }

// Response 201
{ "id": "uuid", "email": "user@example.com", "isChirpyRed": false, "createdAt": "...", "updatedAt": "..." }

POST /api/login

// Request
{ "email": "user@example.com", "password": "hunter2" }

// Response 200
{
  "id": "uuid",
  "email": "user@example.com",
  "isChirpyRed": false,
  "token": "<JWT>",
  "refreshToken": "<hex string>",
  "createdAt": "...",
  "updatedAt": "..."
}

Chirps

Method Endpoint Auth Description
GET /api/chirps None Get all chirps
GET /api/chirps/:id None Get a chirp by ID
POST /api/chirps Bearer JWT Create a new chirp
DELETE /api/chirps/:chirpId Bearer JWT Delete your own chirp

Query Parameters for GET /api/chirps

Param Values Description
authorId UUID Filter chirps by author
sort asc (default) / desc Sort by creation date

POST /api/chirps

// Request
{ "body": "Hello Chirpy world!" }

// Response 201
{ "id": "uuid", "body": "Hello Chirpy world!", "userId": "uuid", "createdAt": "...", "updatedAt": "..." }

Webhooks

Method Endpoint Auth Description
POST /api/polka/webhooks ApiKey Handle Polka payment events

POST /api/polka/webhooks

// Request (Authorization: ApiKey <key>)
{
  "event": "user.upgraded",
  "data": { "userId": "uuid" }
}

// Response 204 (no content)

Admin

Method Endpoint Auth Description
GET /admin/metrics None View file server hit count
POST /admin/reset None Reset hit count (dev only)

Architecture Notes

  • ESM modules — The project uses native ES modules ("type": "module") with .js extensions on all imports.
  • Drizzle ORM — Type-safe SQL queries with schema-driven migrations. No raw SQL strings.
  • Custom error classesBadRequestError, UnauthorizedError, ForbiddenError, NotFoundError map directly to HTTP status codes via a central error handler.
  • wrapAsync pattern — All async route handlers are wrapped to forward errors to Express's error middleware, keeping handler code clean and throw-based.
  • res.locals for auth state — JWT claims are stored in res.locals (not req.body) so auth data survives across middleware on all HTTP methods, including bodyless ones like DELETE.

Future Goals

  • Add rate limiting to prevent chirp spam
  • Paginate GET /api/chirps instead of returning all records
  • Add integration tests using a test database
  • Deploy to a cloud platform (Railway / Fly.io)
  • Support image attachments on chirps
  • Add a GET /api/users/:id public profile endpoint

Links

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors