This is a sample project demonstrating the implementation of a blog service using Domain-Driven Design (DDD) and Layered Architecture principles.
-
interface/: Interface Layer
- controllers: HTTP Request Handling
- middlewares: Middleware Functions
- routes: Route Definitions
-
application/: Application Layer
- services: Application Services
- commands: Command Objects
- errors: Custom Error Classes
-
domain/: Domain Layer
- models: Entities and Value Objects
- services: Domain Services
- repositories: Repository Interface Definitions
-
infrastructure/: Infrastructure Layer
- prisma: Prisma Related Configurations
- repositories: Concrete Repository Implementations
- unit: Unit Tests
- helpers: Test Helper Functions
interface → application → domain ← infrastructure
- Docker
- TypeScript
- Node.js
- Express
- Prisma
- SQLite
- Vitest
- ESLint
- Prettier
- GitHub Actions (CI)
- docker compose up app-dev -d
- docker compose exec app-dev npm run prisma:migrate-dev
- docker compose exec app-dev npm run test
- docker compose exec app-dev npm run test:coverage
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{
"name": "John Doe",
"email": "john@example.com"
}'Expected response (201 Created)
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}curl -X GET http://localhost:3000/api/users/1Expected response (200 OK)
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}curl -X POST http://localhost:3000/api/articles \
-H "Content-Type: application/json" \
-d '{
"title": "My First Article",
"content": "This is the content of my first article.",
"userId": 1
}'Expected response (201 Created)
{
"id": 1,
"title": "My First Article",
"content": "This is the content of my first article.",
"userId": 1,
"createdAt": "2024-12-24T10:00:00.000Z"
}curl -X GET http://localhost:3000/api/articles/1Expected response (200 OK)
{
"id": 1,
"title": "My First Article",
"content": "This is the content of my first article.",
"userId": 1,
"createdAt": "2024-12-24T10:00:00.000Z"
}curl -X GET http://localhost:3000/api/users/1/articlesExpected response (200 OK)
[
{
"id": 1,
"title": "My First Article",
"content": "This is the content of my first article.",
"userId": 1,
"createdAt": "2024-12-24T10:00:00.000Z"
}
]curl -X DELETE http://localhost:3000/api/articles/1/users/1Expected response (204 No Content)
curl -X DELETE http://localhost:3000/api/users/1Expected response (204 No Content)
curl -X POST http://localhost:3000/api/users \
-H "Content-Type: application/json" \
-d '{
"name": "Jane Doe",
"email": "john@example.com"
}'Expected response (409 Conflict)
curl -X POST http://localhost:3000/api/articles \
-H "Content-Type: application/json" \
-d '{
"title": "Invalid Article",
"content": "This article should not be created.",
"userId": 999
}'Expected response (404 Not Found)
curl -X DELETE http://localhost:3000/api/articles/1/users/2Expected response (403 Forbidden)