A professional, production-ready RESTful Todo API built with TypeScript and Express. This application demonstrates best practices in Node.js development including proper project structure, error handling, validation, testing, and code quality tools.
- Full CRUD Operations: Create, Read, Update, and Delete todos
- Statistics Endpoint: Track completed vs pending todos
- Type Safety: Written in TypeScript with strict type checking
- Proper Architecture: Organized with MVC pattern (Models, Controllers, Routes)
- Swagger/OpenAPI: Interactive API documentation at
/api-docs - Request ID Tracking: Unique ID for each request for tracing
- RESTful Design: Clean, intuitive API endpoints
- Security Headers: Helmet.js for secure HTTP headers
- CORS Support: Cross-Origin Resource Sharing enabled
- Rate Limiting: Protection against abuse and DDoS
- Compression: Gzip compression for responses
- Input Validation: Comprehensive request validation with detailed error messages
- Structured Logging: JSON-formatted logs for easy parsing
- Request Logging: Automatic logging of all requests
- Error Handling: Centralized error handling middleware
- Health Check: Endpoint for monitoring service status
- Testing: Comprehensive test suite with Jest and Supertest
- Code Quality: ESLint and Prettier for consistent code style
- Pre-commit Hooks: Husky and lint-staged for automatic code quality checks
- CI/CD Pipeline: GitHub Actions for automated testing and deployment
- Environment Configuration: Dotenv for environment variables
- Docker Support: Containerization with multi-stage builds
- Docker Compose: Easy local development setup
- Code Security: CodeQL analysis and Dependabot
- EditorConfig: Consistent coding styles across editors
todo-api/
├── src/
│ ├── config/ # Configuration files
│ │ └── env.config.ts
│ ├── controllers/ # Request handlers
│ │ └── todo.controller.ts
│ ├── middleware/ # Express middleware
│ │ ├── error.middleware.ts
│ │ ├── logger.middleware.ts
│ │ └── validation.middleware.ts
│ ├── models/ # Data models
│ │ └── todo.model.ts
│ ├── routes/ # API routes
│ │ ├── index.ts
│ │ └── todo.routes.ts
│ ├── types/ # TypeScript type definitions
│ │ ├── express.types.ts
│ │ └── todo.types.ts
│ ├── utils/ # Utility functions
│ │ └── logger.ts
│ ├── app.ts # Express app configuration
│ └── server.ts # Server entry point
├── tests/ # Test files
│ └── todo.test.ts
├── .env.example # Environment variables template
├── .eslintrc.json # ESLint configuration
├── .prettierrc # Prettier configuration
├── jest.config.js # Jest configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Project dependencies and scripts
- Node.js >= 16.0.0
- npm >= 8.0.0
-
Clone the repository
git clone https://github.com/UNC-GDSC/ToDo-APIs.git cd ToDo-APIs -
Install dependencies
npm install
-
Set up environment variables
cp .env.example .env
Edit
.envfile with your configuration:NODE_ENV=development PORT=3000 API_PREFIX=/api
Run the application with auto-reload on file changes:
npm run devBuild and run the compiled application:
npm run build
npm startThe server will start on http://localhost:3000 (or your configured PORT).
Run the application using Docker:
# Build the Docker image
docker build -t todo-api .
# Run the container
docker run -p 3000:3000 --env-file .env todo-api
# Or use Docker Compose
docker-compose up
# Stop the container
docker-compose downAccess the application at http://localhost:3000.
Access the Swagger UI documentation at:
http://localhost:3000/api-docs
The Swagger UI provides:
- Complete API reference with request/response examples
- Interactive testing of all endpoints
- Schema definitions for all data models
- Try-it-out functionality for each endpoint
Base URL: http://localhost:3000/api
GET /health
Check if the API is running.
Response:
{
"success": true,
"message": "Todo API is running",
"timestamp": "2025-11-13T12:00:00.000Z"
}GET /todos
Response:
{
"success": true,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"completed": false,
"createdAt": "2025-11-13T12:00:00.000Z",
"updatedAt": "2025-11-13T12:00:00.000Z"
}
],
"message": "Retrieved 1 todos"
}GET /todos/:id
Response:
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"completed": false,
"createdAt": "2025-11-13T12:00:00.000Z",
"updatedAt": "2025-11-13T12:00:00.000Z"
}
}POST /todos
Request Body:
{
"title": "Buy groceries",
"description": "Milk, eggs, bread"
}Validation Rules:
title(required): String, 1-200 charactersdescription(optional): String, max 1000 characters
Response: (201 Created)
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"completed": false,
"createdAt": "2025-11-13T12:00:00.000Z",
"updatedAt": "2025-11-13T12:00:00.000Z"
},
"message": "Todo created successfully"
}PUT /todos/:id
Request Body:
{
"title": "Buy groceries and cook dinner",
"description": "Updated description",
"completed": true
}Validation Rules:
- At least one field must be provided
title(optional): String, 1-200 charactersdescription(optional): String, max 1000 characterscompleted(optional): Boolean
Response:
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Buy groceries and cook dinner",
"description": "Updated description",
"completed": true,
"createdAt": "2025-11-13T12:00:00.000Z",
"updatedAt": "2025-11-13T12:05:00.000Z"
},
"message": "Todo updated successfully"
}DELETE /todos/:id
Response:
{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Buy groceries",
"description": "Milk, eggs, bread",
"completed": true,
"createdAt": "2025-11-13T12:00:00.000Z",
"updatedAt": "2025-11-13T12:05:00.000Z"
},
"message": "Todo deleted successfully"
}GET /todos/stats
Response:
{
"success": true,
"data": {
"total": 10,
"completed": 6,
"pending": 4
}
}All error responses follow this format:
{
"success": false,
"error": "Error message description"
}Common HTTP status codes:
400- Bad Request (validation errors)404- Not Found500- Internal Server Error
npm run dev- Start development server with auto-reloadnpm run build- Compile TypeScript to JavaScriptnpm run build:clean- Clean build directory and rebuildnpm start- Run compiled applicationnpm test- Run test suite with coveragenpm run test:watch- Run tests in watch modenpm run lint- Check code for linting errorsnpm run lint:fix- Fix linting errors automaticallynpm run format- Format code with Prettiernpm run format:check- Check code formatting
# Run all tests with coverage
npm test
# Run tests in watch mode
npm run test:watchTest coverage report will be generated in the coverage/ directory.
This project uses ESLint and Prettier for code quality and formatting:
# Check for linting issues
npm run lint
# Fix linting issues
npm run lint:fix
# Format code
npm run format- todo.model.ts: In-memory data store and business logic for todos
- todo.controller.ts: Request handlers for todo operations
- todo.routes.ts: Todo endpoint definitions
- index.ts: Main router combining all routes
- error.middleware.ts: Centralized error handling
- logger.middleware.ts: Request/response logging
- validation.middleware.ts: Input validation
- todo.types.ts: Todo-related TypeScript interfaces
- express.types.ts: Express-related TypeScript types
- env.config.ts: Environment variable management and validation
| Variable | Description | Default |
|---|---|---|
NODE_ENV |
Environment (development/production) | development |
PORT |
Server port | 3000 |
API_PREFIX |
API route prefix | /api |
This project includes automated CI/CD pipelines using GitHub Actions:
- Automated Testing: Runs on every push and pull request
- Multi-version Testing: Tests against Node.js 16, 18, and 20
- Code Quality Checks: Linting and formatting verification
- Security Audits: npm audit for dependency vulnerabilities
- Code Coverage: Automated coverage reports with Codecov
- CodeQL Analysis: Automated code security scanning
- Dependabot: Automatic dependency updates
- Vulnerability Alerts: Real-time security notifications
View the workflows in .github/workflows/:
ci.yml- Main CI/CD pipelinecodeql.yml- Security analysis
- Rate limiting
- API documentation with Swagger/OpenAPI
- Docker containerization
- CI/CD pipeline
- Database integration (MongoDB, PostgreSQL)
- User authentication and authorization (JWT, OAuth)
- Pagination for todo lists
- Advanced filtering and sorting
- WebSocket support for real-time updates
- GraphQL API option
- Caching layer (Redis)
- Metrics and monitoring (Prometheus, Grafana)
- Kubernetes deployment manifests
We welcome contributions! Please see CONTRIBUTING.md for detailed guidelines.
Quick start:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add some amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Please read our Code of Conduct before contributing.
This project is licensed under the MIT License - see the LICENSE file for details.
GDSC-UNC
Built with TypeScript, Express, and best practices in mind.