A production-ready e-commerce microservices architecture built with Symfony, FrankenPHP, and Docker. This project demonstrates enterprise-grade software architecture patterns including Domain-Driven Design (DDD), CQRS, Event-Driven Architecture, and Hexagonal Architecture.
- ποΈ Microservices Architecture - Order and Invoice services with clear bounded contexts
- π§ Domain-Driven Design - Clean separation of Domain, Application, and Infrastructure layers
- β‘ CQRS Pattern - Separate command and query buses using Symfony Messenger
- π Event-Driven Architecture - Asynchronous inter-service communication via RabbitMQ
- π FrankenPHP Performance - Blazing-fast PHP application server with worker mode
- π³ Docker Environment - Complete containerized development and production setup
- ποΈ Multi-Database Setup - PostgreSQL with separate databases per microservice
- π§ͺ Comprehensive Testing - Tests with high coverage
- π OpenAPI Documentation - Auto-generated API documentation with Swagger UI
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β Order Service β β Invoice Service β β Shared Domain β
β β β β β β
β β’ Order Creationβ β β’ Invoice Gen β β β’ Value Objects β
β β’ Status Updatesβ β β’ File Upload β β β’ Events β
β β’ Order Queries β β β’ Email Sending β β β’ Exceptions β
βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββββββ
β β β
βββββββββββββββββββββββββΌββββββββββββββββββββββββ
β
βββββββββββββββββββ
β Message Bus β
β (RabbitMQ) β
βββββββββββββββββββ
- Domain: Order lifecycle management
- Database:
app_order
(PostgreSQL) - Responsibilities: Order creation, status updates, order queries
- Events:
OrderCreatedEvent
,OrderShippedEvent
- Domain: Invoice generation and management
- Database:
app_invoice
(PostgreSQL) - Responsibilities: Invoice file uploads, invoice distribution
- Events:
InvoiceUploadedEvent
,InvoiceSentEvent
- Docker (v20.10+)
- Docker Compose (v2.10+)
-
Clone the repository
git clone https://github.com/sergioalmela/symfony-ddd-ecommerce-microservices.git cd symfony-ddd-ecommerce-microservices
-
Build and start the environment
make build make start
-
Set up databases and run migrations
make sf c="doctrine:database:create --connection=order" make sf c="doctrine:database:create --connection=invoice" make sf c="doctrine:migrations:migrate --no-interaction --configuration=config/migrations_order.yaml" make sf c="doctrine:migrations:migrate --no-interaction --configuration=config/migrations_invoice.yaml"
-
Access the application
- API Info: https://localhost
- Health Check: https://localhost/health
- API Documentation: https://localhost/api/doc
- RabbitMQ Management: http://localhost:15673 (admin/!ChangeMe!)
src/
βββ Order/ # Order Microservice
β βββ Application/ # Use cases & handlers
β β βββ Command/ # Write operations
β β βββ Query/ # Read operations
β βββ Domain/ # Business logic
β β βββ Entity/ # Aggregates
β β βββ ValueObject/ # Value objects
β β βββ Event/ # Domain events
β β βββ Repository/ # Domain interfaces
β βββ Infrastructure/ # External adapters
β βββ Http/Controller/ # REST controllers
β βββ Persistence/ # Database implementation
β βββ Listener/ # Event listeners
βββ Invoice/ # Invoice Microservice
β βββ [same structure as Order]
βββ Shared/ # Shared Domain
βββ Domain/
βββ ValueObject/ # Common value objects
βββ Event/ # Event infrastructure
βββ Exception/ # Domain exceptions
# Docker Environment
make build # Build Docker images
make start # Start all services
make down # Stop all services
make logs # View container logs
# Development
make bash # Access PHP container
make cc # Clear Symfony cache
# Database Operations
make order-migrate # Run Order migrations
make invoice-migrate # Run Invoice migrations
make order-migrate-diff # Generate Order migration diff
# Testing & Quality
make test # Run PHPUnit tests
make cs-fix # Fix code style (PHP-CS-Fixer)
make phpstan # Run static analysis
make rector # Run automated refactoring
make qa # Run full quality assurance suite
# Messaging
make sf c="messenger:consume async" # Start message consumer
This project maintains high code quality through:
- PHPStan Level 6: Static analysis with strict type checking
- PHP-CS-Fixer: Modern PHP code style (PSR-12 compatible)
- Rector: Automated refactoring and PHP version upgrades
- PHPUnit: Comprehensive test coverage
- Symfony Insight: Code quality analysis
# Run all tests
make test
# Run specific test groups
make test c="--group=order"
make test c="--group=invoice"
make test c="--group=e2e"
# Run with coverage
make test c="--coverage-html coverage/"
The project follows testing best practices with:
- Unit Tests: To test the use cases and domain logic
- Test Doubles: Fakes, spies, and mocks for isolation
- Builder Pattern: Fluent test data creation
// Example test builder usage
$order = OrderBuilder::anOrder()
->withId(OrderId::generate())
->withPrice(Price::of(29.99))
->withStatus(OrderStatus::PENDING)
->build();
# Database
DATABASE_ORDER_URL=postgresql://app:!ChangeMe!@database:5432/app_order
DATABASE_INVOICE_URL=postgresql://app:!ChangeMe!@database:5432/app_invoice
# Messaging
MESSENGER_TRANSPORT_DSN=amqp://app:!ChangeMe!@rabbitmq:5672/%2f/messages
# Application
APP_ENV=prod
APP_SECRET=your-secret-key
config/packages/messenger.yaml
- Message bus configurationconfig/packages/doctrine.yaml
- Multi-database setupconfig/migrations_order.yaml
- Order service migrationsconfig/migrations_invoice.yaml
- Invoice service migrations
The project includes interactive API documentation powered by OpenAPI/Swagger. Access the documentation at:
π https://localhost/api/doc
This interface allows you to:
- View all available endpoints
- Test API endpoints directly from the browser
- See request/response schemas
- Understand authentication requirements
POST /orders # Create new order
GET /orders # List orders
GET /orders/{orderId} # Get order details
PATCH /orders/{orderId}/status # Update order status
POST /invoices/{orderId}/upload # Upload invoice file
POST /invoices/{invoiceId}/send # Send invoice to customer
# Get API information
curl -X GET https://localhost/
# Check API health
curl -X GET https://localhost/health
# Create an order
curl -X POST https://localhost/orders \
-H "Content-Type: application/json" \
-d '{
"customerId": "01234567-89ab-cdef-0123-456789abcdef",
"sellerId": "01234567-89ab-cdef-0123-456789abcdef",
"productId": "01234567-89ab-cdef-0123-456789abcdef",
"quantity": 2,
"price": 29.99
}'
# Upload invoice (PDF only)
curl -X POST https://localhost/invoices/{orderId}/upload \
-F "sellerId=01234567-89ab-cdef-0123-456789abcdef" \
-F "file=@invoice.pdf"
# Build production images
docker compose -f compose.yaml -f compose.prod.yaml build
# Deploy to production
docker compose -f compose.yaml -f compose.prod.yaml up -d
- FrankenPHP Worker Mode: Application warm-up for faster response times
- OPcache: Bytecode caching enabled in production
- Database Indexing: Optimized database queries
- Message Queue: Asynchronous processing for heavy operations
- Follow PSR-12 coding standards
- Write comprehensive tests
- Use type hints and return types
- Follow SOLID principles
- Maintain high PHPStan level compliance
- Microservices: Enables independent scaling and deployment of business domains
- DDD: Aligns software structure with business domains for better maintainability
- CQRS: Separates read and write operations for optimal performance
- Event-Driven: Enables loose coupling and eventual consistency between services
- Hexagonal: Keeps business logic independent of infrastructure concerns
- Built on top of dunglas/symfony-docker
- Inspired by Domain-Driven Design principles
- Uses modern PHP and Symfony best practices