This is the backend server for a Twitter-like application called "Chirpy". It's built with TypeScript, Node.js, and Express, and it provides a RESTful API for managing users, "chirps" (posts), and authentication.
This project was developed as part of the Boot.dev "Web Servers" course. The course is a culmination of the back-end track, focusing on the fundamental concepts and practical implementation of HTTP servers. It emphasizes building a web server from scratch in TypeScript, understanding its underlying mechanics, and leveraging production-ready tools.
- User Management: Create and update user accounts.
- Authentication: Secure user login with JSON Web Tokens (JWTs) and Refresh Tokens.
- Password Security: Passwords are securely hashed using
bcrypt. - CRUD for Chirps: Full Create, Read, and Delete operations for chirps.
- Content Moderation: Automatically censors a predefined list of "bad words" in chirps.
- Webhook Integration: Listens for webhooks from the "Polka" service to handle user upgrades.
- Database: Uses PostgreSQL with Drizzle ORM for type-safe database queries.
- Migrations: Database schema migrations are handled by Drizzle ORM and run automatically on startup.
- Configuration: Environment-based configuration for easy setup across different environments (dev, staging, prod).
- API Health: Includes health check and basic metrics endpoints.
- Backend: Node.js, Express.js
- Language: TypeScript
- Database: PostgreSQL
- ORM: Drizzle ORM
- Authentication:
jsonwebtoken,bcrypt
Before you begin, ensure you have the following installed:
- Node.js (v18 or higher is recommended)
- A package manager like
npm,yarn, orpnpm - A running PostgreSQL instance
Follow these steps to get the server up and running on your local machine.
git clone <your-repository-url>
cd web-servernpm installCreate a .env file in the root of the project. You can copy the example below and fill in your specific details.
# .env
# Server Configuration
# PORT: The port the server will listen on.
# PLATFORM: The current environment (e.g., "dev", "production"). "dev" allows access to the /admin/reset endpoint.
PORT=8080
PLATFORM=dev
# Database
# DB_URL: Your PostgreSQL connection string.
DB_URL="postgresql://user:password@localhost:5432/database_name"
# JWT
# JWT_SECRET: A strong, unique secret for signing JWTs.
JWT_SECRET="a-very-long-and-super-secret-key-for-jwt"
# Polka Webhook
# POLKA_KEY: The API key for authenticating requests from the Polka service.
POLKA_KEY="your-polka-api-key"The server is configured to run database migrations automatically on startup, so no manual step is needed.
npm startThe server should now be running at http://localhost:8080.
Here is a summary of the available API endpoints.
GET /api/healthz: Health check endpoint. Returns200 OKif the server is running.GET /admin/metrics: Displays an admin HTML page with server visit counts.POST /admin/reset: Resets the database. Only available whenPLATFORM=dev.
-
POST /api/login: Authenticate a user.- Body:
{ "email": "[email protected]", "password": "password123" } - Response (200 OK): User data, JWT, and refresh token.
- Body:
-
POST /api/refresh: Refresh an access token using a valid refresh token.- Headers:
Authorization: Bearer <refresh_token> - Response (200 OK): A new JWT.
- Headers:
-
POST /api/revoke: Revoke a refresh token.- Headers:
Authorization: Bearer <refresh_token> - Response:
204 No Content.
- Headers:
-
POST /api/users: Create a new user.- Body:
{ "email": "[email protected]", "password": "password123" } - Response (201 Created): The new user's data (excluding password).
- Body:
-
PUT /api/users: Update an authenticated user's email and password.- Headers:
Authorization: Bearer <jwt_token> - Body:
{ "email": "[email protected]", "password": "newpassword123" } - Response (200 OK): The updated user's data.
- Headers:
-
POST /api/chirps: Create a new chirp.- Headers:
Authorization: Bearer <jwt_token> - Body:
{ "body": "This is my first chirp!" } - Response (201 Created): The new chirp data.
- Headers:
-
GET /api/chirps: Retrieve all chirps.- Query Params:
authorId=<user_id>(optional): Filter chirps by author.sort=<asc|desc>(optional): Sort chirps by creation date (default:desc).
- Response (200 OK): An array of chirps.
- Query Params:
-
GET /api/chirps/:chirpId: Retrieve a single chirp by its ID.- Response (200 OK): The chirp data.
-
DELETE /api/chirps/:chirpId: Delete a chirp. The authenticated user must be the author.- Headers:
Authorization: Bearer <jwt_token> - Response:
204 No Contenton success,403 Forbiddenif not the author.
- Headers:
POST /api/polka/webhooks: Webhook endpoint for Polka service events.- Headers:
Authorization: ApiKey <polka_api_key> - Body:
{ "event": "user.upgraded", "data": { "userId": "<user_id>" } } - Action: Upgrades a user to "Chirpy Red" status if the event is
user.upgraded. - Response:
204 No Contenton success or for unhandled events.401 Unauthorizedfor an invalid API key.404 Not Foundif the user doesn't exist.
- Headers: