{"id":13411448,"url":"https://github.com/yceruto/symfony-ddd-skeleton","last_synced_at":"2025-04-10T02:28:00.891Z","repository":{"id":40315630,"uuid":"101703070","full_name":"yceruto/symfony-ddd-skeleton","owner":"yceruto","description":"Organize and Manage Multiple Applications with Kernel Contexts.","archived":false,"fork":false,"pushed_at":"2023-12-01T16:53:46.000Z","size":200,"stargazers_count":117,"open_issues_count":1,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2024-05-20T03:20:08.963Z","etag":null,"topics":["ddd","ddd-architecture","multiple-kernels","php","skeleton-application","symfony","symfony-skeleton-application"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/yceruto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-08-29T01:09:40.000Z","updated_at":"2024-07-26T22:20:02.554Z","dependencies_parsed_at":"2024-07-26T22:30:03.172Z","dependency_job_id":null,"html_url":"https://github.com/yceruto/symfony-ddd-skeleton","commit_stats":{"total_commits":88,"total_committers":3,"mean_commits":"29.333333333333332","dds":0.09090909090909094,"last_synced_commit":"453dea22d2ca49933ac057f42092c8fd869b2713"},"previous_names":[],"tags_count":4,"template":true,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yceruto%2Fsymfony-ddd-skeleton","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yceruto%2Fsymfony-ddd-skeleton/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yceruto%2Fsymfony-ddd-skeleton/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/yceruto%2Fsymfony-ddd-skeleton/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/yceruto","download_url":"https://codeload.github.com/yceruto/symfony-ddd-skeleton/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248143894,"owners_count":21054840,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ddd","ddd-architecture","multiple-kernels","php","skeleton-application","symfony","symfony-skeleton-application"],"created_at":"2024-07-30T20:01:13.758Z","updated_at":"2025-04-10T02:28:00.861Z","avatar_url":"https://github.com/yceruto.png","language":"PHP","funding_links":[],"categories":["Web Development","PHP"],"sub_categories":["PHP"],"readme":"# Symfony Multi-Application Project Skeleton\n\nOrganize and Manage Multiple Applications with Kernel Contexts.\n\nThis project skeleton is designed to implement the [Domain-Driven Design](https://en.wikipedia.org/wiki/Domain-driven_design) (DDD) \nand [Hexagonal Architecture](https://en.wikipedia.org/wiki/Hexagonal_architecture_(software)) patterns. It is also well-suited \nfor use in a [microservice](https://en.wikipedia.org/wiki/Microservices) architecture.\n\n### Installation\n\n    composer create-project yceruto/symfony-skeleton ddd\n\n### Context-based Kernel\n\nA context-based kernel in Symfony refers to a custom implementation of the Kernel class that allows for running multiple \napplications, each with its own context (such as `api.example.com` and `admin.example.com`), within a single project repository. \nThe different contexts are transparent to the end-user, but enable a clear separation of concerns and organization of \nthe codebase. \n\nEach context corresponds to a separate and distinct entrypoint (site, api or admin), each with its own set of dedicated \nroutes and configurations. Despite this separation, common code, such as dependencies and business logic, are shared among \nall contexts. The kernel uses the request's context to determine the appropriate entrypoint to handle the request, ensuring \nthat the correct routes and configurations are used for each context.\n\n### Context-based Configuration\n\nThe project structure includes a new `context/` directory where the configuration and presentation-related files are organized \naccording to the kernel context. The `src/` directory contains the core functionality of the application, divided into modules for \nbetter organization and management.\n\n    ├── config/\n    │   ├── packages/\n    │   ├── bundles.php\n    │   └── services.yaml\n    ├── context/\n    │   ├── admin/\n    │   │   ├── config/\n    │   │   │   ├── packages/\n    │   │   │   ├── bundles.php\n    │   │   │   ├── routes.yaml\n    │   │   │   ├── security.yaml\n    │   │   │   └── services.yaml\n    │   │   └── src/\n    │   │       ├── Command/\n    │   │       └── Controller/\n    │   ├── api/\n    │   ├── site/\n    │   └── Kernel.php\n    ├── src/\n    │   ├── Module/\n    │   │   └── SubModule/\n    │   │       ├── Application/\n    │   │       ├── Domain/\n    │   │       └── Infrastructure/\n    │   ├── Shared/\n    │   │   ├── Domain/\n    │   │   ├── Infrastructure/\n    │   │   └── Presentation/\n    ├── var/\n    │   ├── cache/\n    │   │   ├── admin/\n    │   │   │   ├── dev/\n    │   │   │   └── prod/\n    │   │   ├── api/\n    │   │   └── site/\n    │   └── logs/\n\nThe project structure includes subdirectories such as admin, api, and site as part of the kernel context approach. These \ndirectories contain all files and configurations that are specific to each context. In contrast, files and directories such \nas `packages/`, `bundles.php`, and any others located at the root of the `config/` directory are recognized as global configuration \nfor all contexts.\n\nTo optimize performance, each app, as defined by the kernel context, has its own Dependency Injection container file, routing \nconfiguration, and specific settings. However, common elements such as the `vendor/`, `config/`, and `src/` code are shared among \nall the contexts. This approach allows for efficient resource management and organization of the codebase.\n\n### Keeping one entry point for all applications\n\n    ├── public/\n    │   └── index.php\n\nIn line with Symfony 4's philosophy, environment variables can be used to determine the app's mode (dev/test/prod) and \nwhether debug mode is enabled. Additionally, a new environment variable called `APP_CONTEXT` must be created to specify \nthe kernel context that should be run. This can be easily tested using PHP's built-in web server by setting the environment \nvariable before starting the server:\n\n    $ APP_CONTEXT=admin php -S 127.0.0.1:8000 -t public\n    $ APP_CONTEXT=api php -S 127.0.0.1:8001 -t public   \n\n### Use Symfony local webserver\n\nTo run multiple kernel contexts, you will need to use the [Symfony local server](https://symfony.com/doc/current/setup/symfony_server.html) and \nits [proxy](https://symfony.com/doc/current/setup/symfony_server.html#setting-up-the-local-proxy) functionality.\n\nFirst, start the Symfony proxy by running the command `symfony proxy:start` in the project folder.\n\nNext, create a symbolic link ([symlink](https://en.wikipedia.org/wiki/Symbolic_link)) for each of your applications that \npoints to your project folder. These symbolic links can be stored in a folder within your project or outside of it, depending \non your preference.\n\n    ├── links/\n    │   ├── admin\n    |   ├── api\n    |   └── site\n    ├── config/\n    ├── src/\n    └── var/\n\nAfter creating the symbolic links, you will need to configure each local server and start it. This is done by using the \nsymbolic links created earlier. For example, you might run a command such as:\n\n```\n# start admin local server\nAPP_CONTEXT=admin symfony proxy:domain:attach admin --dir=[project folder path]/links/admin\nAPP_CONTEXT=admin symfony server:start --dir=[project folder path]/links/admin\n\n# start api local server\nAPP_CONTEXT=api symfony proxy:domain:attach api --dir=[project folder path]/links/api\nAPP_CONTEXT=api symfony server:start --dir=[project folder path]/links/api\n\n# start site local server\nAPP_CONTEXT=site symfony proxy:domain:attach site --dir=[project folder path]/links/site\nAPP_CONTEXT=site symfony server:start --dir=[project folder path]/links/site\n```\n\nTo verify that each server is running, you can navigate to the appropriate URL in your web browser [localhost:7080](http://localhost:7080).\n\n### Production and vhosts\n\nIn order to run multiple kernel contexts in a production environment or development environment, you will need to set the \nenvironment variable `APP_CONTEXT` for each virtual host configuration. This can be done by modifying the appropriate \nconfiguration files on your production server or development machine, depending on your preference:\n\n    \u003cVirtualHost admin.company.com:80\u003e\n        # ...\n        \n        SetEnv APP_CONTEXT admin\n        \n        # ...\n    \u003c/VirtualHost\u003e\n\n    \u003cVirtualHost api.company.com:80\u003e\n        # ...\n        \n        SetEnv APP_CONTEXT api\n        \n        # ...\n    \u003c/VirtualHost\u003e\n\n### Executing commands per application\n\n    ├── bin/\n    │   └── console.php\n\nUse `--kernel`, `-k` option to run any command for one specific app:\n\n    $ bin/console about -k api\n\nOr if you prefer, use environment variables on CLI:\n\n    $ export APP_CONTEXT=api\n    $ bin/console about                         # api application\n    $ bin/console debug:router                  # api application\n    $\n    $ APP_CONTEXT=admin bin/console debug:router   # admin application\n\nAdditionally, you can set the default `APP_CONTEXT` environment variable in your `.env` file or by modifying the `bin/console` file. \nThis allows you to specify the default kernel context that will be used if the environment variable is not set or overridden elsewhere.\n\n### Running tests per application\n\n    ├── tests/\n    │   └── context/\n    │       ├── admin\n    │       │   └── AdminWebTestCase.php\n    │       └── api/\n\nThe `tests/` directory will include a `context/` directory that mirrors the structure of the `context/` directory in the main codebase. \nTo use this structure in your tests, you will need to update your `composer.json` file to map each directory within `tests/context/\u003cCONTEXT\u003e/`\nto its corresponding PSR-4 namespace. This allows you to test each kernel context separately.\n\n    \"autoload-dev\": {\n        \"psr-4\": {\n            \"Admin\\\\Tests\\\\\": \"tests/context/admin/\",\n            \"Api\\\\Tests\\\\\": \"tests/context/api/\"\n        }\n    },\n\nRun `composer dump-autoload` to re-generate the autoload config.\n\nTo run all the tests for a specific kernel context, create a separate `\u003cCONTEXT\u003eWebTestCase` class for each app. \nThis allows you to execute all the tests together and test each kernel context independently.\n\n### Adding more applications to the project\n\nInstall this bundle in your project:\n\n    $ composer require yceruto/ddd-maker-bundle --dev\n\nTo create a new kernel context skeleton, run the command `bin/console make:ddd:context \u003cCONTEXT\u003e` in the terminal. This will \ngenerate the necessary files and directories for the new kernel context, allowing you to easily add new functionality to \nyour application.\n\nWhen installing new packages that generate new configuration files, it is important to move them to the correct sub-application \ndirectory if they are not intended to work for all applications. Additionally, you should update the `auto-scripts` section \nin `composer.json` to execute each command with the correct kernel option. To ensure that the cache is cleared for each individual \napplication, it is recommended to include the script `\"cache:clear -k \u003cCONTEXT\u003e\": \"symfony-cmd\"` for each app in your `composer.json` file.\n\nLicense\n-------\n\nThis software is published under the [MIT License](LICENSE)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyceruto%2Fsymfony-ddd-skeleton","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fyceruto%2Fsymfony-ddd-skeleton","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fyceruto%2Fsymfony-ddd-skeleton/lists"}