Proof of Concept for a RESTful API made with Node.js LTS/Krypton (v24) and Express.js 5 in TypeScript. Manage football player data with SQLite, Sequelize ORM, Swagger documentation, and in-memory caching.
- Features
- Tech Stack
- Project Structure
- Architecture
- API Endpoints
- Prerequisites
- Quick Start
- Testing
- Docker
- Environment Variables
- Available Scripts
- Contributing
- Legal
- π RESTful CRUD operations for football player data
- πΏ Relational database with ORM
- β‘ In-memory caching (1-hour TTL)
- π Interactive API documentation
- π Security headers and CORS
- π©Ί Health check endpoint for monitoring
- β Comprehensive integration tests
- π³ Full containerization support
- π TypeScript strict mode enabled
- π Hot reload for development
| Category | Technology |
|---|---|
| Runtime | Node.js 24 (LTS/Krypton) |
| Language | TypeScript 5.9 |
| Module System | Native ECMAScript Modules (ESM) - uses tsx for execution |
| Framework | Express.js 5 |
| Database | SQLite3 with Sequelize ORM |
| Caching | node-cache |
| Documentation | Swagger (OpenAPI 3.0) |
| Security | Helmet, CORS |
| Testing | Jest 30 with Supertest |
| Containerization | Docker with multi-stage builds |
| Code Quality | ESLint, Prettier, Commitlint |
| Dev Tools | tsx (TypeScript executor), nodemon |
π‘ Note: While the repository name references
ts-node(the original implementation), the project now uses tsx for faster, cleaner TypeScript execution without experimental flags.
src/
βββ app.ts # Express app setup & middleware configuration
βββ server.ts # HTTP server initialization & lifecycle
βββ controllers/ # Request handlers with Swagger annotations
βββ services/ # Business logic + caching layer
βββ database/ # Sequelize DB access (interfaces + implementations)
βββ models/ # Sequelize models (Player)
βββ routes/ # Express Router definitions
βββ docs/ # Swagger configuration & doc generation
βββ middlewares/ # Custom middleware (swagger CSP)
tests/ # Integration tests with supertest
scripts/ # Docker entrypoint & healthcheck scripts
storage/ # Pre-seeded SQLite database
Layered architecture with dependency injection via constructors and interface-based contracts.
%%{init: {
"theme": "default",
"themeVariables": {
"fontFamily": "Fira Code, Consolas, monospace",
"textColor": "#555",
"lineColor": "#555",
"lineWidth": 2,
"clusterBkg": "#f5f5f5",
"clusterBorder": "#999"
}
}}%%
graph BT
subgraph API[" "]
server[server]
app[app]
routes[routes]
controllers[controllers]
Express[Express]
end
subgraph Business[" "]
services[services]
nodeCache[node-cache]
end
subgraph Data[" "]
database[database]
models[models]
Sequelize[Sequelize]
end
%% Tests (outside layers)
tests[tests]
%% Detailed connections within layers
database --> services
models --> database
models --> services
models --> controllers
services --> controllers
controllers --> routes
routes --> app
app --> server
%% External Dependencies
Sequelize --> database
Sequelize --> models
nodeCache --> services
Express --> controllers
Express --> routes
Express --> app
%% Tests connection
app -.-> tests
%% Styling
classDef core fill:#b3d9ff,stroke:#6db1ff,stroke-width:2px,color:#555,font-family:monospace;
classDef deps fill:#ffcccc,stroke:#ff8f8f,stroke-width:2px,color:#555,font-family:monospace;
classDef test fill:#ccffcc,stroke:#53c45e,stroke-width:2px,color:#555,font-family:monospace;
class server,app,routes,controllers,services,database,models core
class Express,Sequelize,nodeCache deps
class tests test
Simplified, conceptual project structure and main application flow. Not all dependencies are shown.
Interactive API documentation is available via Swagger UI at http://localhost:9000/swagger/ when the server is running.
Quick Reference:
GET /players- List all playersGET /players/:id- Get player by IDGET /players/squadNumber/:squadNumber- Get player by squad numberPOST /players- Create new playerPUT /players/:id- Update playerDELETE /players/:id- Remove playerGET /health- Health check
For complete endpoint documentation with request/response schemas, explore the interactive Swagger UI. You can also access the OpenAPI JSON specification at http://localhost:9000/swagger.json.
Before you begin, ensure you have the following installed:
- Node.js 24 (LTS/Krypton) or higher
- npm (comes with Node.js)
- Docker and Docker Compose (optional, for containerized setup)
git clone https://github.com/nanotaboada/ts-node-samples-express-restful.git
cd ts-node-samples-express-restfulnpm installnpm run devThe server will start on http://localhost:9000 with the following output:
> [email protected] dev
> nodemon
[nodemon] to restart at any time, enter `rs`
[nodemon] watching path(s): src/**/*
[nodemon] watching extensions: ts
[nodemon] starting `tsx ./src/server.ts`
π Running at http://localhost:9000- API:
http://localhost:9000 - Swagger Documentation:
http://localhost:9000/swagger/ - Health Check:
http://localhost:9000/health
Run the test suite with Jest:
# Run all tests
npm test
# Run tests with coverage report
npm run coverage
# Run linter
npm run lint
# Validate commit message format
npm run lint:commitTests are located in the tests/ directory and use Supertest for integration testing. Coverage reports are generated for controllers, services, and routes only.
This project includes full Docker support with multi-stage builds and Docker Compose for easy deployment.
npm run docker:build
# or
docker compose buildnpm run docker:up
# or
docker compose upπ‘ Note: On first run, the container copies a pre-seeded SQLite database into a persistent volume. On subsequent runs, that volume is reused and the data is preserved.
npm run docker:down
# or
docker compose downTo remove the volume and reinitialize the database from the built-in seed file:
docker compose down -vThe containerized application runs on port 9000 and includes health checks that monitor the /health endpoint every 30 seconds.
Create a .env file in the root directory to customize configuration:
# Server port (default: 9000)
PORT=9000
# Database storage path (default: storage/players-sqlite3.db)
# In Docker: /storage/players-sqlite3.db
STORAGE_PATH=storage/players-sqlite3.db| Script | Description |
|---|---|
npm run dev |
Start development server with hot reload |
npm start |
Run compiled application from dist/ |
npm run build |
Compile TypeScript to JavaScript |
npm test |
Run Jest tests with --detectOpenHandles flag |
npm run coverage |
Generate test coverage report |
npm run lint |
Run ESLint on all files |
npm run lint:commit |
Validate last commit message format |
npm run swagger:docs |
Generate swagger.json from JSDoc annotations |
npm run docker:build |
Build Docker image |
npm run docker:up |
Start Docker container |
npm run docker:down |
Stop and remove Docker volume |
Contributions are welcome! Please read CONTRIBUTING.md for details on the code of conduct and the process for submitting pull requests.
Key guidelines:
- Follow Conventional Commits for commit messages
- Ensure all tests pass (
npm test) - Run linter before committing (
npm run lint) - Keep changes small and focused
This project is provided for educational and demonstration purposes and may be used in production environments at your discretion. All referenced trademarks, service marks, product names, company names, and logos are the property of their respective owners and are used solely for identification or illustrative purposes.