Skip to content
← Back to articles

Article

Hexagonal Architecture and Messaging with PHP

Hexagonal Architecture (Ports and Adapters)

Project link: https://github.com/sschonss/microservices-hexagonal

There are many ways to organize a project, and one of the best known is hexagonal architecture. Hexagonal architecture organizes a project so that it is independent of frameworks, databases, UI and so on. The goal is for the project to be independent of any technology, so that each one can be easily replaced.

In this project, hexagonal architecture was implemented with the PHP programming language and the Laravel framework. The idea is for the project to be independent of Laravel, so we use Laravel only to create routes and controllers, and the rest of the project does not depend on it.

Project structure

The project was split into 3 main layers:

Adapters

Adapters are responsible for adapting the project's inputs and outputs. But what does that mean?

Imagine you have a project that needs to talk to a database. Without an adapter layer, you would have to use the database directly in your project. That means using the database classes directly in your code, which makes your project dependent on the database.

An ORM (Object Relational Mapping) is an example of an adapter. The ORM is a layer that adapts communication with the database, so the project does not depend on the database itself.

In our project, we have the following adapters:

They contain the classes that adapt communication with the email service and with RabbitMQ.

All of this uses plain PHP, without Laravel, so the project stays independent and each piece can be easily replaced.

Core

The core is the layer that holds the project's business rules. Inside the core, we will work with Domain Driven Design (DDD).

What is DDD?

Domain Driven Design is a way of organizing a project so that it is split into domains. Each domain is a part of the project that holds business rules. This keeps the project organized and easy to maintain.

Inside the core, we have the following domains:

Inside each domain, we have the layers that hold the business rules for each feature.

Most importantly, the core depends on nothing. It is independent of any framework, database, etc. That way, we can easily replace Laravel with another framework, or MySQL with another database.

The core talks to external services through the adapters. That way, the core does not depend on any external service, only on the adapter.

The project

The project is a simple example of how hexagonal architecture can be implemented. It is a user registration system, where users can sign up and receive a welcome email.

The project was split into 3 services:

This way, the Main App does not depend on RabbitMQ or on the email service. It just sends a message to RabbitMQ, and RabbitMQ delivers the message to the email service.

How to run the project

To run the project, you need Composer, Docker and Docker Compose installed on your machine.

After installing Docker and Docker Compose, just run the following command:

cd main-app composer install ./vendor/bin/sail up

After running the command, the project will be running on port 80.

We can now create a user through the POST /api/user endpoint, sending the following JSON:

{ "name": "John Doe", "email": "john@doe.com", "password": "123456" }

After the user is created, an event is published to RabbitMQ, but the email service is not running yet. To run it, just run the following command:

cd email-app docker-compose up --build --force-recreate

After running the command, the email service will be running, reading messages from RabbitMQ and sending an email to the user.

Accessing RabbitMQ

To access RabbitMQ, just open the following address:

http://localhost:15672

And log in with the following credentials:

Username: guest Password: guest

Conclusion

Hexagonal architecture is a way of organizing a project so that it is independent of any technology. In this project, it was implemented with PHP and the Laravel framework. The idea is for the project to be independent of Laravel, so we use Laravel only to create routes and controllers, and the rest of the project does not depend on it.

The project is a simple example of how hexagonal architecture can be implemented. It is a user registration system, where users can sign up and receive a welcome email.

We also implemented a messaging service with RabbitMQ and an email service. This way, the Main App does not depend on RabbitMQ or on the email service. It just sends a message to RabbitMQ, and RabbitMQ delivers it to the email service.

We saw how messaging helps decouple services, and how hexagonal architecture helps organize a project so that it is independent of any technology.

Share LinkedIn WhatsApp X

Get new articles by email

One email when a new article comes out, in English and Portuguese. No spam, unsubscribe anytime.

Comments