Create complete REST API CRUD operations using API Platform 4 with DDD and CQRS patterns...
Implement production-ready REST API CRUD operations following DDD, CQRS, and hexagonal architecture patterns.
Success Criteria:
make ci outputs "โ
CI checks successfully passed!"Template examples reference MongoDB/Doctrine ODM. In this service, use Doctrine ORM with MySQL (
.orm.xmlmappings,EntityManagerInterface) while keeping the same layering and DTO/processor patterns.
Full Implementation Example: See examples/complete-customer-crud.md for detailed code.
Create pure PHP entity in src/Core/{Context}/Domain/Entity/{Entity}.php
Create config/doctrine/{Entity}.mongodb.xml with field mappings and indexes.
See: database-migrations skill for XML mapping patterns.
Create three DTOs in src/Core/{Context}/Application/DTO/:
{Entity}Create - For POST requests{Entity}Put - For PUT requests (full update){Entity}Patch - For PATCH requests (partial update)See: reference/dto-validation-patterns.md
Create config/validator/{Entity}.yaml with validation rules for each DTO.
Create config/api_platform/resources/{entity}.yaml:
App\Core\{Context}\Domain\Entity\{Entity}:
shortName: { Entity }
operations:
ApiPlatform\Metadata\GetCollection: ~
ApiPlatform\Metadata\Get: ~
ApiPlatform\Metadata\Post:
input: App\Core\{Context}\Application\DTO\{Entity}Create
processor: App\Core\{Context}\Application\Processor\Create{Entity}Processor
ApiPlatform\Metadata\Put:
input: App\Core\{Context}\Application\DTO\{Entity}Put
processor: App\Core\{Context}\Application\Processor\Update{Entity}Processor
ApiPlatform\Metadata\Patch:
input: App\Core\{Context}\Application\DTO\{Entity}Patch
processor: App\Core\{Context}\Application\Processor\Patch{Entity}Processor
ApiPlatform\Metadata\Delete: ~
See: reference/configuration-patterns.md for detailed patterns.
Create config/serialization/{Entity}.yaml to control which fields are exposed.
Create processors in src/Core/{Context}/Application/Processor/:
Create{Entity}Processor - Handles POSTUpdate{Entity}Processor - Handles PUTPatch{Entity}Processor - Handles PATCHEach processor:
Create:
Application/Command/{Action}{Entity}Command.phpApplication/CommandHandler/{Action}{Entity}CommandHandler.phpHandler contains business logic and calls repository.
See: implementing-ddd-architecture for CQRS patterns.
Create:
Domain/Repository/{Entity}RepositoryInterface.phpInfrastructure/Repository/{Entity}Repository.phpconfig/services.yamlSee: database-migrations skill for repository patterns.
Add filters in config/services.yaml for search, ordering, etc.
See: reference/filters-and-pagination.md
REST Request โ API Platform
โ
Processor (Application)
โ
DTO โ Transformer โ Command
โ
Command Bus
โ
Handler (Application)
โ
Entity (Domain) โ Repository (Infrastructure)
โ
MongoDB
See: reference/configuration-patterns.md for detailed architecture.
make deptrac)make ci before committingGET /api/{entities} # List all
GET /api/{entities}/{id} # Get one
POST /api/{entities} # Create
PUT /api/{entities}/{id} # Full update
PATCH /api/{entities}/{id} # Partial update
DELETE /api/{entities}/{id} # Delete
make generate-openapi-spec
# Generates .github/openapi-spec/spec.yaml
โ
CI checks successfully passed!
After implementation:
api_platform.yamlmake deptrac passes (no violations)make ci passes (all checks green)# Clear cache after config changes
make cache-clear
# Generate OpenAPI spec
make generate-openapi-spec
# Validate architecture
make deptrac
# Run E2E tests
make behat
# Full CI check
make ci
For detailed patterns and examples:
Throughout documentation, placeholders follow these conventions:
| Placeholder | Example | Usage |
|---|---|---|
{Entity} |
Customer |
PascalCase class name |
{Context} |
Customer |
Bounded context/module name |
{entity} |
customer |
Lowercase for configs/filters |
{entities} |
customers |
Plural for collection names |
{Action} |
Create, Update |
Command action verb |