[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"project-8562":3},{"id":4,"name":5,"fullName":6,"owner":7,"repo":5,"description":8,"homepage":9,"htmlUrl":10,"language":11,"languages":10,"totalLinesOfCode":10,"stars":12,"forks":13,"watchers":14,"openIssues":15,"contributorsCount":16,"subscribersCount":16,"size":16,"stars1d":16,"stars7d":17,"stars30d":18,"stars90d":16,"forks30d":16,"starsTrendScore":19,"compositeScore":20,"rankGlobal":10,"rankLanguage":10,"license":10,"archived":21,"fork":21,"defaultBranch":22,"hasWiki":21,"hasPages":21,"topics":23,"createdAt":10,"pushedAt":10,"updatedAt":44,"readmeContent":45,"aiSummary":46,"trendingCount":16,"starSnapshotCount":16,"syncStatus":17,"lastSyncTime":47,"discoverSource":48},8562,"php-ddd-example","CodelyTV\u002Fphp-ddd-example","CodelyTV","🐘🎯 Hexagonal Architecture + DDD + CQRS in PHP using Symfony 7","https:\u002F\u002Fpro.codely.tv\u002Flibrary\u002Fddd-en-php",null,"PHP",3137,1084,82,23,0,2,3,1,31.11,false,"main",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"behat","bounded-context","codely","codelytv","cqrs","ddd","docker","doctrine","domain-driven-design","hexagonal-architecture","laravel","microservice","microservices-architecture","monorepo","php","php8","phpunit","symfony","symfony5","testing","2026-06-12 02:01:55","\u003Cp align=\"center\">\n  \u003Ca href=\"https:\u002F\u002Fcodely.com\">\n    \u003Cpicture>\n      \u003Csource media=\"(prefers-color-scheme: dark)\" srcset=\"https:\u002F\u002Fcodely.com\u002Flogo\u002Fcodely_logo-dark.svg\">\n      \u003Csource media=\"(prefers-color-scheme: light)\" srcset=\"https:\u002F\u002Fcodely.com\u002Flogo\u002Fcodely_logo-light.svg\">\n      \u003Cimg alt=\"Codely logo\" src=\"https:\u002F\u002Fcodely.com\u002Flogo\u002Fcodely_logo.svg\">\n    \u003C\u002Fpicture>\n  \u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Ch1 align=\"center\">\n  🐘🎯 Hexagonal Architecture, DDD & CQRS in PHP\n\u003C\u002Fh1>\n\n\u003Cp align=\"center\">\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCodelyTV\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCodely-OS-green.svg?style=flat-square\" alt=\"Codely Open Source projects\"\u002F>\u003C\u002Fa>\n    \u003Ca href=\"http:\u002F\u002Fpro.codely.tv\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FCodelyTV-PRO-black.svg?style=flat-square\" alt=\"CodelyTV Courses\"\u002F>\u003C\u002Fa>\n    \u003Ca href=\"#\">\u003Cimg src=\"https:\u002F\u002Fimg.shields.io\u002Fbadge\u002FSymfony-7-purple.svg?style=flat-square&logo=symfony\" alt=\"Symfony 7\"\u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fshepherd.dev\u002Fgithub\u002FCodelyTV\u002Fphp-ddd-example\">\u003Cimg src=\"https:\u002F\u002Fshepherd.dev\u002Fgithub\u002FCodelyTV\u002Fphp-ddd-example\u002Fcoverage.svg\" alt=\"Type Coverage\"\u002F>\u003C\u002Fa>\n    \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCodelyTV\u002Fphp-ddd-example\u002Factions\">\u003Cimg src=\"https:\u002F\u002Fgithub.com\u002FCodelyTV\u002Fphp-ddd-example\u002Fworkflows\u002FCI\u002Fbadge.svg?branch=master\" alt=\"CI pipeline status\" \u002F>\u003C\u002Fa>\n\u003C\u002Fp>\n\n\u003Cp align=\"center\">\n  Example of a \u003Cstrong>PHP application using Domain-Driven Design (DDD) and Command Query Responsibility Segregation\n  (CQRS) principles\u003C\u002Fstrong> keeping the code as simple as possible.\n  \u003Cbr \u002F>\n  \u003Cbr \u002F>\n  Take a look, play and have fun with this.\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCodelyTV\u002Fphp-ddd-example\u002Fstargazers\">Stars are welcome 😊\u003C\u002Fa>\n  \u003Cbr \u002F>\n  \u003Cbr \u002F>\n  \u003Ca href=\"https:\u002F\u002Fwww.youtube.com\u002Fwatch?v=1kaP39W80zQ\">View Demo\u003C\u002Fa>\n  ·\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCodelyTV\u002Fphp-ddd-example\u002Fissues\">Report a bug\u003C\u002Fa>\n  ·\n  \u003Ca href=\"https:\u002F\u002Fgithub.com\u002FCodelyTV\u002Fphp-ddd-example\u002Fissues\">Request a feature\u003C\u002Fa>\n\u003C\u002Fp>\n\n## 🚀 Environment Setup\n\n### 🐳 Needed tools\n\n1. [Install Docker](https:\u002F\u002Fwww.docker.com\u002Fget-started)\n2. Clone this project: `git clone https:\u002F\u002Fgithub.com\u002FCodelyTV\u002Fphp-ddd-example php-ddd-example`\n3. Move to the project folder: `cd php-ddd-example`\n\n### 🛠️ Environment configuration\n\n1. Create a local environment file (`cp .env .env.local`) if you want to modify any parameter\n\n### 🔥 Application execution\n\n1. Install all the dependencies and bring up the project with Docker executing: `make build`\n2. Then you'll have 3 apps available (2 APIs and 1 Frontend):\n   1. [Mooc Backend](apps\u002Fmooc\u002Fbackend): http:\u002F\u002Flocalhost:8030\u002Fhealth-check\n   2. [Backoffice Backend](apps\u002Fbackoffice\u002Fbackend): http:\u002F\u002Flocalhost:8040\u002Fhealth-check\n   3. [Backoffice Frontend](apps\u002Fbackoffice\u002Ffrontend): http:\u002F\u002Flocalhost:8041\u002Fhealth-check\n\n### ✅ Tests execution\n\n1. Install the dependencies if you haven't done it previously: `make deps`\n2. Execute PHPUnit and Behat tests: `make test`\n\n## 👩‍💻 Project explanation\n\nThis project tries to be a MOOC (Massive Open Online Course) platform. It's decoupled from any framework, but it has\nsome Symfony and Laravel implementations.\n\n### ⛱️ Bounded Contexts\n\n- [Mooc](src\u002FMooc): Place to look in if you wanna see some code 🙂. Massive Open Online Courses public platform with users, videos, notifications, and so on.\n- [Backoffice](src\u002FBackoffice): Here you'll find the use cases needed by the Customer Support department in order to manage users, courses, videos, and so on.\n\n### 🎯 Hexagonal Architecture\n\nThis repository follows the Hexagonal Architecture pattern. Also, it's structured using `modules`.\nWith this, we can see that the current structure of a Bounded Context is:\n\n```scala\n$ tree -L 4 src\n\nsrc\n|-- Mooc \u002F\u002F Company subdomain \u002F Bounded Context: Features related to one of the company business lines \u002F products\n|   `-- Videos \u002F\u002F Some Module inside the Mooc context\n|       |-- Application\n|       |   |-- Create \u002F\u002F Inside the application layer all is structured by actions\n|       |   |   |-- CreateVideoCommand.php\n|       |   |   |-- CreateVideoCommandHandler.php\n|       |   |   `-- VideoCreator.php\n|       |   |-- Find\n|       |   |-- Trim\n|       |   `-- Update\n|       |-- Domain\n|       |   |-- Video.php \u002F\u002F The Aggregate of the Module\n|       |   |-- VideoCreatedDomainEvent.php \u002F\u002F A Domain Event\n|       |   |-- VideoFinder.php\n|       |   |-- VideoId.php\n|       |   |-- VideoNotFound.php\n|       |   |-- VideoRepository.php \u002F\u002F The `Interface` of the repository is inside Domain\n|       |   |-- VideoTitle.php\n|       |   |-- VideoType.php\n|       |   |-- VideoUrl.php\n|       |   `-- Videos.php \u002F\u002F A collection of our Aggregate\n|       `-- Infrastructure \u002F\u002F The infrastructure of our module\n|           |-- DependencyInjection\n|           `-- Persistence\n|               `--MySqlVideoRepository.php \u002F\u002F An implementation of the repository\n`-- Shared \u002F\u002F Shared Kernel: Common infrastructure and domain shared between the different Bounded Contexts\n    |-- Domain\n    `-- Infrastructure\n```\n\n#### Repository pattern\n\nOur repositories try to be as simple as possible usually only containing 2 methods `search` and `save`.\nIf we need some query with more filters we use the `Specification` pattern also known as `Criteria` pattern. So we add a\n`searchByCriteria` method.\n\nYou can see an example [here](src\u002FMooc\u002FCourses\u002FDomain\u002FCourseRepository.php)\nand its implementation [here](src\u002FMooc\u002FCourses\u002FInfrastructure\u002FPersistence\u002FDoctrineCourseRepository.php).\n\n### Aggregates\n\nYou can see an example of an aggregate [here](src\u002FMooc\u002FCourses\u002FDomain\u002FCourse.php). All aggregates should\nextend the [AggregateRoot](src\u002FShared\u002FDomain\u002FAggregate\u002FAggregateRoot.php).\n\n### Command Bus\n\nThere is 1 implementations of the [command bus](src\u002FShared\u002FDomain\u002FBus\u002FCommand\u002FCommandBus.php).\n1. [Sync](src\u002FShared\u002FInfrastructure\u002FBus\u002FCommand\u002FInMemorySymfonyCommandBus.php) using the Symfony Message Bus.\n\n\n### Query Bus\n\nThe [Query Bus](src\u002FShared\u002FInfrastructure\u002FBus\u002FQuery\u002FInMemorySymfonyQueryBus.php) uses the Symfony Message Bus.\n\n### Event Bus\n\nThe [Event Bus](src\u002FShared\u002FInfrastructure\u002FBus\u002FEvent\u002FInMemory\u002FInMemorySymfonyEventBus.php) uses the Symfony Message Bus.\nThe [MySql Bus](src\u002FShared\u002FInfrastructure\u002FBus\u002FEvent\u002FMySql\u002FMySqlDoctrineEventBus.php) uses a MySql+Pulling as a bus.\nThe [RabbitMQ Bus](src\u002FShared\u002FInfrastructure\u002FBus\u002FEvent\u002FRabbitMq\u002FRabbitMqEventBus.php) uses RabbitMQ C extension.\n\n## 📱 Monitoring\n\nEvery time a domain event is published it's exported to Prometheus. You can access to the Prometheus panel [here](http:\u002F\u002Flocalhost:9999\u002F).\n\n## 🤔 Contributing\n\nThere are some things missing (add swagger, improve documentation...), feel free to add this if you want! If you want\nsome guidelines feel free to contact us :)\n\n## 🤩 Extra\n\nThis code was shown in the [From framework coupled code to #microservices through #DDD](http:\u002F\u002Fcodely.tv\u002Fblog\u002Fscreencasts\u002Fcodigo-acoplado-framework-microservicios-ddd) talk and doubts where answered in the [DDD y CQRS: Preguntas Frecuentes](https:\u002F\u002Fcodely.com\u002Fblog\u002Fddd-cqrs-preguntas-frecuentes) video.\n\n\n🎥 Used in the CodelyTV Pro courses:\n\n- [🇪🇸 DDD in PHP](https:\u002F\u002Fpro.codely.tv\u002Flibrary\u002Fddd-en-php\u002Fabout\u002F)\n- [🇪🇸 Arquitectura Hexagonal](https:\u002F\u002Fpro.codely.tv\u002Flibrary\u002Farquitectura-hexagonal\u002F66748\u002Fabout\u002F)\n- [🇪🇸 CQRS: Command Query Responsibility Segregation](https:\u002F\u002Fpro.codely.tv\u002Flibrary\u002Fcqrs-command-query-responsibility-segregation-3719e4aa\u002F62554\u002Fabout\u002F)\n- [🇪🇸 Comunicación entre microservicios: Event-Driven Architecture](https:\u002F\u002Fpro.codely.tv\u002Flibrary\u002Fcomunicacion-entre-microservicios-event-driven-architecture\u002F74823\u002Fabout\u002F)\n\n## 🌐 remember to visit our courses\n\n- [Courses codely](https:\u002F\u002Fcodely.com\u002Fcursos)\n","CodelyTV\u002Fphp-ddd-example 是一个使用 PHP 和 Symfony 7 构建的示例项目，展示了如何应用六边形架构、领域驱动设计（DDD）以及命令查询职责分离（CQRS）原则。该项目通过保持代码尽可能简洁来实现这些模式，并支持 Docker 容器化部署，便于快速搭建开发环境。它包含两个后端服务和一个前端应用，非常适合用于学习现代软件架构设计、测试驱动开发及微服务架构实践。此外，本项目还提供了详尽的文档和自动化测试配置，帮助开发者理解和上手相关技术栈。","2026-06-11 03:18:37","top_language"]