galbenu.ro

Modular monolith

Nov
2018

Monoliths are OK. There is nothing wrong with a good designed monolith. But what qualifies as a good monolith? In my opinion,  it means modular = composed of modules.

A module is a subdivision that is independent of the other subdivisions. It has all the data needed to respond to an external request. This implies that, when a client sends a command or a query to this module, it may not call other modules to get the data. It may use only data that it owns.

If a module needs data from other modules, which is often the case, it may get that data only outside the client’s request, i.e. in the background. By client I mean any requester that lives outside this module, i.e. a human, an API or other module.

The cleanest way to get external data is by using domain/integration events or by subscribing to queries, when it is possible. There are other ways, but by using events is by far my preferred way.

You know that you have a modular monolith when you delete a module and the application still works, of course, without the functionality provided by the deleted module. The widgets, the buttons, the components or the pages owned by that module are just missing. As a concrete example, when you delete the Statistics module, all the stats counters and the stats charts will be missing but the containing pages will continue to work, without any fatal error. The page should also load faster.

Developing a modular monolith depends on the programming language. I’m mainly a PHP developer, with a C++ background (and a former Captain of the armed forces 🙂 ). I think PHP is great for backend web application so my examples refer to PHP. I strongly encourage you read this even though you are not using PHP.

Next I will present the rules that I follow when developing a modular monolith.

Rule 1: Each modules must have it’s own dependency injection container

This is first step to ensure that every module is independent. The Application that combine the modules has also a dependency injection container (DIC), named the default container, and it delegates the resolving of dependencies down to each module’s DIC. The default DIC detects cross-module dependencies. In order to respect the DRY principle, it also resolves common/shared services.

Each module’s DIC is registered to the default DIC by specifying it’s instance and the namespaces that it handles.

Example of a modular monolith

In the image above you can see the src/ directory, where all the modules are placed, along with the app/ (the application) and shared/ (libraries).

The expanded module is Catalog, where the products are described, with texts, images, characteristics and so on. 

  1. the config/ directory contains the DIC and the routes. 
  2. the src/ contains the source code; it is organized in layers;
  3. the src/Catalog is the domain layer, that has no dependency to any other layers;
  4. the other directories are self describing.

Rule 2: A module may not depend on other modules

There should be no service injected from other modules; there must be a way to detect cross-module dependencies; only Events, Commands and Queries may be used;

Rule 3: Each UI Component must provide its own resources

Each UI Component (just Component from now on) must provide its own CSS or Images. A Component must be organized in a directory that contains all the code and it’s resources;

Example of a modular component

You can see in the above picture how a component is organized. The component is called EditareProdusComponent. It has a PHP class, EditareProdusComponent.php and a directory where all the resources are defined. A SCSS file, a JS file and a PHP renderer.

The JS and SCSS files are referenced from the renderer file, like this:

$plugins->headCss->add(__DIR__ . '/editare-produs.scss');
echo $plugins->js->requireModule(__DIR__ . '/editare-produs.js');

$plugins is an Application component that gathers all the resources, translates their URLs and references them in the body of the rendered page, i.e. in the <head> or at the end of the <body> tag.

Each Component should use its own ReadModel, specially designed to respond as fast as possible to queries. If this is not feasible, then each sub-module should use its own ReadModel. For example, all components from the Product editing sub-module could share the same EditingProductDetailsReadModel.

Rule 4: Each modules should declare its own dependencies

In PHP, each module should have a composer.json file and should be installed with composer.

The Application will reference the individual modules in its composer.json file.

The ModularContainer

In order for the Application to resolve services in the modules, it uses a special DIC: the ModularContainer. This delegates the resolving to the individual containers and ensures that a module will not call another module. It uses the Composition pattern. The initialization of the container is done as it follows:

$container = new ModularContainer();

$container->setDefaultModuleNamespaces(["Gica", "Ui"]);

$appContainer = (require __DIR__ . '/../src/app/config/composition-root.php')($container);
$container->setDefaultContainer($appContainer);
$container->addModuleContainer([], $appContainer);
$container->addModuleContainer(['Drei\\Catalog', 'Drei\\CatalogUi', 'Drei\\CatalogInfrastructure', 'Drei\\CatalogProcesses', 'Import'], (require __DIR__ . '/../src/catalog/config/composition-root.php')($container));
$container->addModuleContainer(['Drei\\Forum'], (require __DIR__ . '/../src/forum/config/composition-root.php')($container));
$container->addModuleContainer(['Drei\\Identity', 'Drei\\IdentityInfrastructure', 'Drei\\IdentityUi',], (require __DIR__ . '/../src/identity/config/composition-root.php')($container));
$container->addModuleContainer(['Drei\\Developer', ], (require __DIR__ . '/../src/developer/config/composition-root.php')($container));
$container->addModuleContainer(['Drei\\InscriereOnline', 'Drei\\InscriereOnlineUi', 'Drei\\InscriereOnlineAdmin', ], (require __DIR__ . '/../src/inscriere-online/config/composition-root.php')($container));
$container->addModuleContainer(['Drei\\Statistici', 'Drei\\StatisticiInfrastructure', ], (require __DIR__ . '/../src/statistici/config/composition-root.php')($container));

$container->setService(ContainerInterface::class, $container);
$container->setService(ModularContainer::class, $container);

The Application

Composing modules is done in the Application, which is just a collection of Web Pages/Actions referenced by routes. Each Web page uses Components from different modules to generate the HTML/JSON fragments, assembles them using Layouts and return them to the user/browser. This has many advantages:

  • Single responsibility principle: the Application and the individual modules have only one reason to change; the Application changes only when the Components are added/removed/rearranged, in other words, only when the layout changes.
  • Separation of concerns: each Component knows/cares only about its business and the Application only cares about assembling the pieces.
  • Possibility to load the individual Components in parallel, speeding the page load time.

Conclusion

Creating a modular monolith is hard. There are many obstacles that must be overtaken but it is doable. One should not just create microservices from the beginning. I think this step, the modular monolith, is a required step before entering the microservices world.

Moto or Google?

Oct
2018

I have this super phone: Moto Z. I just love it. I really do.
At the beginning of this year it started to act weird when trying to take picture: it would just shut down. Out of the blue, no matter how charged or discharged the battery was. As I said, I love my Moto so I thought to myself: I bought this phone to be a phone not a camera, so ignored the issue. A few months ago, the shut down started to happen whenever I opened a not phone app: WhatsApp, Facebook and Facebook Messenger. So I started to search the web. And because there is a lot of junk I found some articles about how Google and Facebook are in some sort of war. And I immediately thought: is my phone weird because of that? So I uninstalled all Facebook apps or what I know to belong to Facebook). But imagine my surprise when. I found that my Moto Z would shut down on twitter, camera, even when visiting some pages on chrome. Then I started to blame Motorola. Sorry Guys 🙁
I even reset my phone, wiped chace partition and nothing.

So what should I do now? Buy a pixel phone? I see that it is the only one acting as a phone should. So what did you do Google? And Lenovo, do you not care about your Moto phones? I do! Please fix it.

Who gets the credit?

Feb
2018

On Twitter, there is a “Like” button. What is it for? if one clicks it, do they show appreciation for the content of what has been tweeted or for the action of having tweeted something?
I believe that it is there for the content and I click it to show I appreciate what has been written.

On Twitter there is also a “Retweet” button. What is it for?
I believe it is used to share tweets that one found interesting and they want to share it with their fellow followers. At least that is how I use it.

Now, what does it mean if you like a retweet? This is how I see it: you like the content that has been retweeted. Right? Good. That means that all attention will go to the re-tweeter and very little to the original? (that is assuming the re-tweeter has a lot more followers that the initial author, of course)
Then what about the initial author of the retweeted tweet? Do they not deserve appreciation for having shared a piece of interesting information? Then instead of “liking” the retweet, why not like the original? you click on the retweet anyway to read it. Or do you? And to quote a famous meme on the internet: “Do you mean to tell me…” that you do not read the content of the retweet? you just like and/or retweet after you only read the title? That is even worse than not crediting the author.

(more…)

[inline] Styling in React – #ReactEurope

Jan
2018

I would begin with a 5 minute refresh on CSS.

The next 10-12 minutes will be about how and why to apply inline styles in React. I will share my ups and downs, and what I learned – like sometimes it really is necessary to put the styles inline.
I am dedicating part of the talk for the style attribute: what is is and how is/should it be used – focusing on the fact that it accepts a JavaScript object rather then a a CSS string; prefixes for different browsers are also included here.

The last past of the talk is about a more modern approach: styled components. I am sharing this part as a JS alternative to inline styling.

Bank Holiday vs. Holiday

Jan
2018

A bank holiday is a colloquial term for a public holiday in the United Kingdom, some Commonwealth countries, Hong Kong and the Republic of Ireland.

– Wikipedia

A bank holiday is a day in which banks (and maybe other businesses) are closed. There are, however days that banks and businesses are closed that are not bank holidays: Christmas Day, Good Friday.

So people of the world if your country does not designate a special day for the banks to be off, then it is not a bank holiday!

So, why do us, the rest of the world refer to any holiday as “bank holiday”?

Short answer: Because we are ignorant.

Long answer: We are ignorant and we are too lazy to do our research. We just use words and expressions we hear around without knowing their meaning. We just assume we can figure it out from the context. Surprise: we can not! Why? because you can not possibly match the context 100%.

Should a developer care about the business?

Jan
2018

Yesterday I was in a meeting with my team lead (backend dev), another backend dev, a business analyst and a designer. The designer kept asking questions about the admin panel of the app, about the technical limitations, what is out-of-the box and what not so that she can design a solution that will not be too creative for our limitations.

And after the team lead answered all her questions and the meeting is over, the other backend says (with an annoyed voice):

“Why should I, as a programmer, care about the business. Why do I need to know about all of this stuff. I know PHP and that’s it. How can we create high performance if I care about the business”

At the time it just seemed odd to hear that from a programmer (and a backend, no less), but I said nothing. I just paused. Now, a day later, after I processed the words I ask: How can you not care about the business? How can you provide the client with the best possible solution if you do not know and understand his business, the roles, the client types, the products, the categories – everything that is business related? How?

How to make a developer feel unwelcome

Jan
2018

It’s December 15th 2017 and I am happily starting a new job that promises a lot.

I arrive at the office around 11am. They usually start at 10, but since here no one really comes in time…

As I said, I arrive around 11am and I go straight to the HR department (because HR is the only contact I have). There I am invited to sit at a desk until the IT guys will bring my laptop because they do not know what my project is going to be nor what team I am part of. I know I am frontend and I will work with Magento2. 2 minutes later the IT guy comes and says:

“Let’s go to the other floor. There’s where you’ll live”.

We arrive at my desk, I see a laptop (with a nasty scratch on the exterior of the lid). It looks kind of old to me, but I think maybe I should not complain from the first 30 minutes. The It guys helps me connect to the wi-fi and hands me and envelope saying: and this is the envelope. He sounded as if I knew what that envelope is. Again, I don’t ask about it, thinking i will figure it out, or maybe it is self explanatory. Then he leaves.

(more…)

I am John and I solved a problem

Dec
2017

I am John, I work for a company whose name I can not say and we have this client, but I am not allowed to mention their name, and we had this problem for which I cannot give specifics but I am here to tell you about how we implemented the solution.

Sounds familiar? Maybe, maybe not.

Well, for me this is the thing I hear at almost every conference I attend. Truth be told, I can understand that one can not give specifics, but one should also not start a topic meant to teach others unless you are willing to go into specifics.

I have the feeling that these “Johns” want to create the impression that they encountered a million problems and found at least one solution for each.

But how do I know that the problem was not created due to a faulty logic? How do we (the attendees) know if maybe the requirement was stated or understood in the wrong way. Usually that is where the problem stands. And it is best to ask all the questions before starting to work.

Anyhow, there are speakers for whom I would travel half the planet, but there are also others that have fancy job titles and do not have a clue of what’s going on in the dev world.

So, conference organizers: please, please I would rather see the same 3 speakers in all the conferences than having different poorly prepared speakers, just for the sake of not repeating.

And for the speakers: Please speak for the sake of sharing and making the community better not for the money. Remember why you became a programmer! If money is the first answer, you are doing it wrong.

Petr (or how to lose a great developer in under 3 months)

Dec
2017

Once upon a time, in April this year, I was moving to a new company. It looked really good especially since they said that they have “Nordic (Danish) management”. All good until end on July when I had some well-deserved vacation.

In mid-July this new developer Petr Čaněk joined my project as developer. I knew nothing about him even though something was a bit off in the way he talked (choice of expressions, tone, attitude, frequency of words per minute, lack of article usage…), but hey! we are all unique and as long as the company decided to bring him in I was convinced that they made the best decision, so I welcomed him to the team, made sure that he had access everywhere he needed and then left for vacation.

After I came back, we had a meeting with the client and out project manager could not join but we (PM, team and client) had an agreement that I would be his stand-in (not only that one time but every time he would not be there). For some reason Petr felt the need to say – out loud – that this team had no project manager and because of that reason we are chaotic. I immediately responded that this statement is not true. We do have a project manager, but since he is not here, I am his stand-in, as agreed. I asked him if I could be of any help in this role, and when he said “no” I suggested we should continue the meeting. A few days later I receive a call from my line manager (in short: a person responsible with the relationship between me and the company) saying that Petr complained to him about me not doing my job – there were over 10 untouched tasks in my backlog. I cleared the problem (or at least  thought I did) as it was a misunderstanding that lead to so many tasks being created. My line manager also informed me that out PM would be changed (the reason was that the new PM already has the rest of this client’s projects).

After this things only went down.

(more…)

Colour of the year 2018

Dec
2017

If you haven’t decorated you house yet or at least the Christmas Tree I (or better: Pantone) give you colour of the year 2018: Ultra Violet!.