A simple e-commerce system built with modern, popular technologies, showcasing advanced software architecture patterns and best practices.
This project is kind of sandbox for me for experimenting and learning new techniques and technologies. It’s more meant to be an ongoing project rather than something finished once and for all. I also see it as a great way to showcase my work and coding skills. Not everything here is optimized for maximum efficiency and how I would approach to these problems in real commercial projects - some parts, such as the communication between the payment microservice and the monolith, are intentionally implemented using mixed - sync and async communication because I wanted to test pros and cons and that's for me best way of learning something in efficient way.
This diagram shows structure of database - separated databases per module/service, with data replication rather than a shared database.
For now CI is only configured for backend.
At the beginning, when I started this project to learn Symfony, I made it as a simple monolith. Later, I decided to learn about the modular monolith, and then the hexagonal architecture. That’s how this project has been evolving alongside my experience and curiosity about learning new approaches and technologies. The main application is built in PHP with Symfony as a modular monolith, where one module is a simple authentication service and the other, commerce, is a bit more complex. The payments microservice is written in Go using the Gin framework. Both the monolith and the payments microservice are made using ports and adapters architecture and also CQRS.
Each module or microservice has it own context -> for example same entity representation in auth service will be named user - in clients module it is client - payments service it is payer, records are replicated through whole system. Each module or service has own separate database. Replication of data is only done when it's necessary -> for example when someone tries to make purchase without account (unique id is associated to email) then records is only being created in payments and clients modules. Only when user decide to make account then record with given id and email is being created in user module. Modules in monolith have also separated databases so you can say easily this is configuration is ready for separating monolith to microservices. With common database it would be much harder and in my opinion microservices with common databases are not as powerful as with separated.
- Queries handle read operations (search products, get order details)
- Sync Commands handle write operations that needs to be done instantly (create product, update order status)
- Async Commands for operations that can be delayed or might take some time to complete (email notifications)
Start the development environment
cd development && ./build.shAccess the application
- Frontend: http://localhost:3000
- Backend API: http://localhost/api/v1
- API Documentation: http://localhost/api/doc
- RabbitMQ Management: http://localhost:15672
- MailHog: http://localhost:8025
The API is available at http://localhost/api/doc
- PHPStan for static analysis
- PHPCS for coding standards
- Deptrac for architecture enforcement
- PHPUnit for testing
./bin/tests.shminikube start --driver=docker
minikube addons enable storage-provisioner





