The game is implemented as an example of scalable and high load architecture combined with modern software development practices
Packaging approach | Branch | HEAD |
---|---|---|
By features | feature/package-by-feature | master |
By layers | feature/package-by-layer |
RabbitMQ - need for handling commands and events asynchronous via the Symfony Messenger component.
Elasticsearch - used as storage for dictionary with 10,000 english and 10,000 russian words from the box.
Redis - used as a cache for generated crosswords.
SQLite - used as the main storage for player data and his game history.
To simplify the development and sharing of code, the Monorepository code storage approach was chosen. Each module of the system is independents, and they can be separated like an independent microservice and communicate by API.
To integrate existing, or a new modules applied solutions like the Port and Adapters pattern.
Ports are represented by Interfaces - {modue}\Domain\Port
These implementations will be the adapter - {modue}\Infrastructure\Adapter
:
ApiAdapter
- used to API communicate with another moduleDirectAdapter
- used to direct communicate with another moduleInMemoryAdapter
- used to mock module in teh tests
To make the code organised each module uses Layered Architecture and each functional area is divided on four layers:
Application
Doman
Infrastructure
UI
Switch to check it feature/package-by-layer
👍 Checked by Deptrac
Action Domain Responder organizes a single user interface interaction between an HTTP client and a HTTP server-side application into three distinct roles.
Domain-driven design is not a technology or a methodology. It is a way of thinking and a set of priorities, aimed at accelerating software projects that have to deal with complicated domains.
On a macro level using DDD concepts like Ubiquitous Language and Bounded Contexts can solve complex perspectives on data in to smaller models and clear data ownership. Follow practices splitting the source code based on bounded contexts we define a next context:
- Crossword - algorithm for building crosswords
- Dictionary - words storage
- Game - game functionality
For reducing duplication of code we use a SharedKernel
, it helps share a common code between context.
The docker-compose up command aggregates and run each container.
docker network create game
make start
Open in browser
https://app.test:1001/game/play
Swagger help to describe the structure of APIs for better understand how is it works.
👍 URL: /swagger
Сollections with queries can be found: cd /postman
👍 Checked by Newman
- PHP 8.0
- Symfony 5.2
- Elasticsearch
- RabbitMQ
- Redis
- SQLite
- phpunit
- phpcs
- psalm
- rector
- phpcs-calisthenics-rules
- newman
- deptrac
- SPL
- Value objects
- Data transfer objects
- Implementing Action-Domain-Responder Pattern With Symfony
- Package by Feature
- Domain events
Dykyi Roman, e-mail: mr.dukuy@gmail.com