An Express + TypeScript API for managing a movie catalog with PostgreSQL and Sequelize. This API allows you to create, update, delete, and fetch movies and categories, with proper validation, error handling, and a clean architecture using OOP principles.
- Language: TypeScript
- Framework: Express
- Database: PostgreSQL
- ORM: Sequelize
- Environment Variables: dotenv
- Validation: Zod (or Joi if preferred)
- Architecture: Hexagonal (Ports and Adapters)
- OOP: Classes, Interfaces, and SOLID Principles
src/
βββ application/ # Use Cases - Business logic
β βββ services/ # Service classes for business operations
β βββ dto/ # Data Transfer Objects
β βββ interfaces/ # Application-level interfaces (ports)
βββ domain/ # Core Domain
β βββ entities/ # Domain models (classes, interfaces)
β βββ repositories/ # Repository interfaces (ports)
β βββ exceptions/ # Domain-specific exceptions
βββ infrastructure/ # Adapters & Infrastructure
β βββ api/ # Express routes and controllers
β βββ db/ # Database connection and repositories (adapters)
β βββ validation/ # Validation schemas
β βββ middleware/ # Express middleware
β βββ config/ # Environment and configuration files
βββ shared/ # Shared utilities (e.g., logger, error handling)
βββ index.ts # Entry point - Express app setup
βββ package.json
βββ tsconfig.json
DB_CONTAINER_NAME=movie_db
DB_HOST=localhost
DB_PORT=5432
DB_USER=admin
DB_PASSWORD=my_secret_password
DB_NAME=movies_db
DB_DIALECT=postgres
API_CONTAINER_NAME=movies-api
API_IMAGE_NAME=web-api:1.0.0
API_HOST=http://localhost
API_PORT=3000
API_CLIENT_URL=http://localhost:3000
Field | Type | Description |
---|---|---|
id |
INTEGER (PK) | Unique identifier |
title |
STRING | Movie title |
description |
TEXT | Movie description |
categoryId |
INTEGER (FK) | Reference to Category |
createdAt |
DATE | Record creation date |
updatedAt |
DATE | Record update date |
Field | Type | Description |
---|---|---|
id |
INTEGER (PK) | Unique identifier |
name |
STRING | Category name |
createdAt |
DATE | Record creation date |
updatedAt |
DATE | Record update date |
- POST
/api/movies
- Create a new movie - GET
/api/movies/:id
- Get movie details by ID - GET
/api/movies
- Get a paginated list of movies (filter by title/category) - PUT
/api/movies/:id
- Update a movie - DELETE
/api/movies/:id
- Delete a movie
- POST
/api/categories
- Create a new category - GET
/api/categories
- Get all categories - GET
/api/categories/:id
- Get category details by ID - PUT
/api/categories/:id
- Update a category - DELETE
/api/categories/:id
- Delete a category (only if no movies are linked)
- Required Fields: Ensure required fields are present.
- Data Types: Validate types (string, number, etc.).
- Constraints: Unique, non-null constraints.
- Movies: Supports pagination with
page
andlimit
query params. - Filtering: Filter movies by
title
orcategoryId
.
- 404: Resource not found.
- 400: Validation errors.
- 500: Internal server errors.
This application has been thoroughly tested using Jest, a JavaScript testing framework.
- All tests are located inside the
__tests__
directory. - The tests cover controllers, services, and repository layers.
- The application includes unit and integration tests to validate API endpoints.
To execute the tests, run the following command:
npm run test
The latest test run successfully passed all test cases:
Test Suites: 2 passed, 2 total
Tests: 40 passed, 40 total
Snapshots: 0 total
Time: 3.423 s
Ran all test suites.
The tests include:
-
Movies API (
/movies
)- β Retrieve all movies (paginated, sorted, and filtered)
- β Retrieve a movie by ID
- β Create a new movie (with validation checks)
- β Update a movie (validations & duplicate handling)
- β Soft delete a movie
-
Categories API (
/categories
)- β Retrieve all categories (paginated, sorted, and filtered)
- β Retrieve a category by ID
- β Create a new category (validations & duplicate handling)
- β Update a category
- β Delete a category (checks for associated movies)
/__tests__
βββ categoryRoutes.test.ts # Tests for category endpoints
βββ movieRoutes.test.ts # Tests for movie endpoints
git clone https://github.com/HouseCham/express-api.git
cd express-api
npm install
npx sequelize-cli db:migrate --config src/infrastructure/config/config.js
npm run test
npm run build
npm run dev
or
npm run start
Server will run at: http://localhost:3000