This project is an exercise to implement a clean, modular architecture for a Node.js REST API using Domain-Driven Design (DDD) principles, TypeScript, and tsoa for OpenAPI documentation. The domain modeled here is a simple order management system.
- Domain-Driven Design: Clear separation of domain, application, infrastructure, and API layers.
- TypeScript: Strong typing and modern language features.
- Validation: Input validation using DTOs and value objects.
- Custom Error Handling: Consistent error responses with custom error classes.
- Repository Pattern: Easily swap data storage implementations.
- Logging: Structured logging for debugging and monitoring.
- OpenAPI Documentation: Auto-generated API docs via tsoa.
src/
application/ # Application services (use cases)
order.service.ts
controllers/ # API controllers (HTTP layer)
order.controller.ts
domain/ # Domain layer (entities, repositories, value objects)
order.entity.ts
order.repository.ts
value-objects/
email-address.vo.ts
dtos/ # Data Transfer Objects (API boundary)
create-order.dto.ts
retrieve-order.dto.ts
errors/ # Custom error types
api.errors.ts
event/ # Domain or integration events
order.event-handler.ts
infrastructure/ # Infrastructure implementations (e.g., persistence)
in-memory-order.repository.ts
shared/ # Shared utilities
validate.ts
app.ts # Express app setup
routes.ts # API route definitions
server.ts # Server entry point
swagger.json # OpenAPI spec (generated)
- Order Entity: Represents an order with properties like
id,userId,productIds, andcreatedAt. - Value Objects: Encapsulate domain rules (e.g.,
EmailAddressfor email validation). - Repository Interface: Abstracts data access for orders.
- POST
/orders - Request Body:
{ "userId": "string", "productIds": ["string", ...] } - Responses:
201 Created: Order created successfully.400 Bad Request: Invalid input data.409 Conflict: Resource already exists.500 Internal Server Error: Unexpected error.
- GET
/orders - Responses:
200 Success: Returns a list of orders.500 Internal Server Error: Unexpected error.
Custom error classes provide consistent error responses:
BadRequestErrorConflictErrorInternalServerError- Others as needed
Controllers catch and map errors to appropriate HTTP status codes.
- DTOs: Use
class-validatordecorators for input validation. - Value Objects: Enforce domain invariants (e.g., valid email format).
-
Install dependencies:
npm install
-
Build the project:
npm run build
-
Start the server:
npm start
-
API Documentation:
Visit/docs(or/swagger) for interactive OpenAPI docs.
- Unit tests can be added for services, domain entities, and controllers.
- Use your preferred test runner (e.g., Jest, Mocha).
- Add new domain entities, value objects, or aggregates as needed.
- Implement additional repository types (e.g., database, external API).
- Add domain events for side effects (e.g., notifications).
MIT