PHPackages                             landingi/modular-monolith-bundle - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. landingi/modular-monolith-bundle

ActiveSymfony-bundle

landingi/modular-monolith-bundle
================================

Landingi Modular Monolith bundle

v1.0.1(4y ago)027.1kMITPHPPHP &gt;=7.4

Since Mar 18Pushed 4y ago1 watchersCompare

[ Source](https://github.com/landingi/modular-monolith-bundle)[ Packagist](https://packagist.org/packages/landingi/modular-monolith-bundle)[ RSS](/packages/landingi-modular-monolith-bundle/feed)WikiDiscussions master Synced 3d ago

READMEChangelog (2)Dependencies (4)Versions (3)Used By (0)

[![Build Status](https://camo.githubusercontent.com/f47df64eadfddaa7bdab5f9836296177139c5d2d7e5f3f5c11bf17bdbc17fd7f/68747470733a2f2f7472617669732d63692e636f6d2f6c616e64696e67692f6d6f64756c61722d6d6f6e6f6c6974682d62756e646c652e7376673f6272616e63683d6d6173746572)](https://travis-ci.com/landingi/modular-monolith-bundle)[![License MIT](https://camo.githubusercontent.com/2a09bd237643d62ac044b1e554f3153bcdc48c1a476ccdfcba9713539f286fd1/68747470733a2f2f696d672e736869656c64732e696f2f61706d2f6c2f76696d2d6d6f64652e737667)](https://opensource.org/licenses/MIT)[![Packagist Version](https://camo.githubusercontent.com/8a998cebe1ea703617e4d66871b41794e7ece0ae5c7d1bb12f1e494e9638131c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c616e64696e67692f6576656e742d73746f72652d62756e646c65)](https://camo.githubusercontent.com/8a998cebe1ea703617e4d66871b41794e7ece0ae5c7d1bb12f1e494e9638131c/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6c616e64696e67692f6576656e742d73746f72652d62756e646c65)

Modules in Modular Monolith
===========================

[](#modules-in-modular-monolith)

From the point of view of a modular monolith, it is important not to introduce code level coupling between its modules.

Communication
-------------

[](#communication)

Communication within a modular monolith between specific modules should not introduce code level couplings. Each module must be treated as a separate element of the system (we can even say that each module is a microservice inside the monolith). In order to meet such requirements, communication between modules can be carried out in two ways, depending on the specific demand.

The way of communication is modeled on that presented by Bottega (Devmentors) in their example Modular Monolith written in .net technology. The idea was absorbed and adapted to PHP technology (unfortunately, not everything could be done as nicely and generically as in .net).

- *(NOT READY)* We can react to public events (application / integration) from the point of view of the module.
- *(READY)* We can throw requests to a specific module using a mechanism similar to the Http protocol. This implementation is now ready and usable. The whole thing works completely inside the memory which guarantees high performance.

In the event-driven architecture, communication mainly takes place through integration events. However, not everything is playable by events. These are mainly modules containing generic contexts that can be used by multiple modules. Here, "module requests" comes to our aid.

### 1. Integration/application events

[](#1-integrationapplication-events)

*(To be implemented)*

### 2. Module requests

[](#2-module-requests)

The idea behind requests between modules using what we have termed "module request" is to be able to communicate between modules within a modular monolith as if we had a distributed architecture in the case of microservices. This allows us to run the project without introducing hacks and couplings between specific elements of the system. In addition, the implementation allows you to easily extract a specific module as a microservice, if necessary.

Of course, the current implementation is just the beginning. It supports the basic assumptions, but there is probably room for improvement. The current implementation is inside the memory, if one day one of the modules is pulled out as a microservice beyond a monolith, then a new ModuleClient implementation should be added to support communication via the infrastructure.

#### 2. 1. How it works?

[](#2-1-how-it-works)

Any module wishing to make a certain resource available for other modules should add "request handler" at a specific path (the path should be in a format similar to that of HTTP, for example: "module/acl/v1/is-functionality-granted". Subscribing at this time all requests going to this path in the same way as we would do in the case of API via HTTP, except that everything happens by default in memory (of course, extracting the module as a microservice and changing communication is not a problem as I mentioned before).

So we are registering the handler in Symfony DI using tag: `app.module.handler` with given request path: `module/acl/v1/is-functionality-granted`:

```
Acl\Application\ModuleRequest\Handler\IsFunctionalityGrantedHandler:
    arguments: ['@Acl\Application\Service\AccessService']
    tags:
        - { name: 'app.module.handler', path: 'module/acl/v1/is-functionality-granted' }
```

This handler will handle requests to ACL to check permissions from the other modules, and again exactly in the same way as it would be in HTTP API.

Then, from the level of another module, e.g. lightboxes, we can easily introduce the ACL checking service (remember that each module is an individual entity). In this service we will simply call via `ModuleClient` our created handler without any code level coupling:

```
use SharedKernel\Application\Module\GenericMessage;

$accountUuid = 'c87ceb7b-4272-4126-abeb-1d778ff89ed2';
$userUuid = '639e4f08-d176-4c15-9f2f-94ad69d6ccd9';
$functionalityPermission = 'lightboxes.view_list';

$result = $this->moduleClient->request(
    'module/acl/v1/is-functionality-granted',
    new GenericMessage(
        [
            'account_uuid' => (string) $accountUuid,
            'user_uuid' => (string) $userUuid,
            'permission' => $functionalityPermission
        ]
    )
);
```

In the `$result` variable we will simply get our handler result. Exactly the same way as we would while calling the HTTP API.

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity21

Limited adoption so far

Community11

Small or concentrated contributor base

Maturity53

Maturing project, gaining track record

 Bus Factor2

2 contributors hold 50%+ of commits

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~60 days

Total

2

Last Release

1821d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/859d0bbd1ef0d0772cf6c515be1510752ba68743d03e84435ee7b2e6117a08f2?d=identicon)[Ferror](/maintainers/Ferror)

![](https://www.gravatar.com/avatar/ad7e3714f206fe283305d9a48fe8bcf4d650b34e5649a67737c5e99801fdcf68?d=identicon)[devofdisaster](/maintainers/devofdisaster)

---

Top Contributors

[![devofdisaster](https://avatars.githubusercontent.com/u/4033768?v=4)](https://github.com/devofdisaster "devofdisaster (1 commits)")[![Ferror](https://avatars.githubusercontent.com/u/17534504?v=4)](https://github.com/Ferror "Ferror (1 commits)")[![mateuszpapis](https://avatars.githubusercontent.com/u/62886012?v=4)](https://github.com/mateuszpapis "mateuszpapis (1 commits)")

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/landingi-modular-monolith-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/landingi-modular-monolith-bundle/health.svg)](https://phpackages.com/packages/landingi-modular-monolith-bundle)
```

###  Alternatives

[scheb/2fa

Two-factor authentication for Symfony applications (please use scheb/2fa-bundle to install)

578630.7k1](/packages/scheb-2fa)[stfalcon/tinymce-bundle

This Bundle integrates TinyMCE WYSIWYG editor into a Symfony2 project.

2692.9M24](/packages/stfalcon-tinymce-bundle)[shopware/core

Shopware platform is the core for all Shopware ecommerce products.

595.2M386](/packages/shopware-core)[symfony/ai-bundle

Integration bundle for Symfony AI components

30282.3k6](/packages/symfony-ai-bundle)[rikudou/psr6-dynamo-db-bundle

PSR-6 and PSR-16 cache implementation using AWS DynamoDB for Symfony

2077.8k](/packages/rikudou-psr6-dynamo-db-bundle)[leapt/core-bundle

Symfony LeaptCoreBundle

2529.1k4](/packages/leapt-core-bundle)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
