Build a full Express API in TypeScript that manages students and their projects. This task brings together everything from Lessons 1–4.

You’ll work with two related in-memory entities:

  • Students
  • Projects (each belongs to a student)

Project Setup

  1. Set up your project from scratch:
    • Use TypeScript with tsconfig.json
    • Use .env with a custom port (PORT=4000)
    • Add scripts in package.json: dev, build, start
    • Use express.json(), CORS, and custom logging middleware
    • Use a global request counter middleware (X-Request-Count)
    • Set up error and 404 middleware properly

Student Routes

Create and manage students first.

Data Structure:

interface Student {
  id: number;
  name: string;
  email: string;
}

Endpoints:

  • GET /students → Get all students
  • GET /students/:id → Get one student
  • POST /students → Create a student
    • Must include name and valid email
  • PUT /students/:id → Replace a student
  • PATCH /students/:id → Update part of a student
  • DELETE /students/:id → Delete a student

Validation:

  • id must be a number
  • name and email required on POST/PUT
  • Return 400 for bad input, 404 for not found

Project Routes

Only create projects after students exist.

Data Structure:

interface Project {
  id: number;
  studentId: number;
  title: string;
  grade: number; // 0–100
}

Endpoints:

  • GET /projects → All projects
  • GET /projects/:id → One project
  • GET /students/:id/projects → All projects for one student
  • POST /projects → Create a project
    • Must include studentId, title, and grade
    • Must check that studentId exists
  • PUT /projects/:id → Replace a project
  • PATCH /projects/:id → Update part of a project
  • DELETE /projects/:id → Delete a project

Query Params (optional):

  • GET /projects?minGrade=80 → Filter by grade
  • GET /projects?studentId=3 → Filter by student
  • GET /projects?sort=grade → Sort by grade (highest first)

Connecting Arrays: Use filter() to connect students and projects. For example, to get all projects for a student: projects.filter(p => p.studentId === studentId).


Authorization

Security Note: The authentication used in this task is for learning purposes only and is not production-ready security. In Module 3, you’ll learn proper authentication with JWT tokens and real security practices.

  • Only GET routes are public
  • All POST, PUT, PATCH, DELETE require:
Authorization: Bearer greatpassword
  • If missing → 401
  • If wrong → 403

Middleware & Error Handling

  • ✅ Logging middleware (method, URL, timestamp)
  • ✅ Timing middleware (log how long each request takes)
  • ✅ Global request counter with X-Request-Count header
  • ✅ 404 middleware for unknown routes
  • ✅ Error handler middleware (send 500 and message if uncaught)

Deliverables

Your API should:

  • Be fully working in TypeScript
  • Support full CRUD on both students and projects
  • Validate data and handle all common errors
  • Use all required middleware
  • Be tested with Postman, curl, or your own frontend
Tags: