
Hello everybody, my name is Alex. And I want to present you my PHP framework for creating micro services. It is based on my experiments in this area, then it has become a pet project, and then I have created several projects, wich are based on this framework.
When I have started developing it, I what to make solution wich:
- can be easily used in the existing projects and legacy code;
- have ability to create simple things fast;
- be neat and expressive;
- use abilities of the modern PHP.
What will be the first step? Sources of course )It can be found on github
And to start fast lets create the first hello world application.
First of all, we need to understand how our endpoints will be called.
If you are using Apache, then you can create .htaccess file, with the following content:
# use mod_rewrite for pretty URL support
RewriteEngine on
RewriteRule ^([a-z0-9A-Z_\/\.\-\@%\ :,]+)/?(.*)$ index.php?r=$1&%{QUERY_STRING} [L]
RewriteRule ^/?(.*)$ index.php?r=index&%{QUERY_STRING} [L]
It will allow you to call endpoints like thishttps://localhost/hello-world/
But if you are using nginx or don’t want to use .htaccess then you can call endpoints in this way:https://localhost/?r=hello-world
And now we’re ready to create our first micro service. It will consists of one endpoint, wich will handle GET requests and return information that he is OK ) A sort of health check.
First of all, we need to add our framework to the project:
composer require mezon/mezon
Then include autoload.php
require_once(autoload.php');
And the first class will look like this:
classTodoServiceextends\Mezon\Service\ServiceBaseimplements\Mezon\Service\ServiceBaseLogicInterface{/* class body */}
More details about it:
ServiceBase – base class for all micro services with the most common functionality;
ServiceBaseLogicInterface – this interface must be implemented by class if it contains endpoint handlers. It does not yet force you to implement methods, it is just made for more strict typization.
And now we are ready to implement the first endpoint handler:
publicfunctionactionPing(){return('I am alive!');}
And then launch it:
\Mezon\Service\Service::start(TodoService::class);
Let’s combine all lines of code and look at the whole picture:
/** * Service class */classTodoServiceextends\Mezon\Service\ServiceBaseimplements\Mezon\Service\ServiceBaseLogicInterface{/** * First endpoint */publicfunctionactionPing(){return('I am alive!');}}\Mezon\Service\Service::start(TodoService::class);
You may want to ask me – wich URL should we call? The truth is that if you have method with the name action it means that framework will automatically create handler for the URL In our case it will look like thishttps://localhost/ping/
By the way: capital letters will be replaced on lower case letters prefixed with ‘-’. For example the method actionHelloWorld will become handler for the next URL:https://localhost/hello-world/
Let’s dig deeper.
All of you know good practices for applilcations. For example, MVC (or any other pattern of the same kind). We have the same story in the world of micro services. I mean that all things wich must be isolated better keep isolated.
In our case service’s class should do one thing – combine parts of this puzzle and logic should be in another class. To do this let’s modify our code as shown below:
classTodoLogicextends\Mezon\Service\ServiceBaseLogic{/** * First endpoint */publicfunctionactionPing(){return('I am alive!');}}classTodoServiceextends\Mezon\Service\ServiceBase{}\Mezon\Service\Service::start(TodoService::class,TodoLogic::class);
You may notice that we have created separate class with our logic:
classTodoLogicextends\Mezon\Service\ServiceBaseLogic
It is derived from the classServiceBaseLogic (it provides some functions wich will be described further).
The classTodoService is no longer implements the interfaceServiceBaseLogicInterface, but now the classServiceBaseLogic implements it.
After the logic was excluded from the service class and moved to the logic class we have got quite empty class. And it can be completely removed:
classTodoLogicextends\Mezon\Service\ServiceBaseLogic{/** * First endpoint */publicfunctionactionPing(){return('I am alive!');}}\Mezon\Service\Service::start(\Mezon\Service\ServiceBase::class,TodoLogic::class);
In this example the service is launched by default classServiceBase, not our custom one.
Let’s dig even more deeper.
After I have used this framework in several projects I have got quite huge classes with tons of busyness logic. From one side it was hurting my eyes, and from the other side Sonar Cube have raised lots of errors, and finally it was not clear how implement strategy of separating read- and write methods (i.e. CQRS).
That’s why I have implemented the feature wich allows group handlers within separate classes with logic. And it allows to use them within on service or in separate ones.
For example, you can implement the whole CRUD logic in one service. But you can also split methods in two groups:
- group of methods for reading data (R in CRUD);
- and group of methods for changing data (CUD in CRUD).
And as an illustration let’s add several new methods:
classTodoSystemLogicextends(\Mezon\Service\ServiceBaseLogic{publicfunctionactionPing(){return('I am alive!');}}/** * Read logic implementation */classTodoReadLogicextends(\Mezon\Service\ServiceBaseLogic{publicfunctionactionList(){return('List!');}}/** * Write logic implementation */classTodoWriteLogicextends(\Mezon\Service\ServiceBaseLogic{publicfunctionactionCreate(){return('Done!');}}\Mezon\Service\Service::start(\Mezon\Service\ServiceBase::class,[TodoSystemLogic::class,TodoReadLogic::class,TodoWriteLogic::class]);
Let’a review main changes:
- we have created classes with logicTodoSystemLogic (system methods),TodoReadLogic (read methods),TodoWriteLogic (data change methods);
- when the service is launched we pass several classes with logics as parameters, not one like in the previous examples.
Well that’s all for today. Other abilities of the framework will be described in the next article. There are a lot of thigs to be shown. And for now visitrepository of the project
Learn more
More information can be found here:
It will be great if you will contribute something to this project. Documentation, sharing the project in your social media, bug fixing, refactoring, or evensubmitting issue with question or feature request. Thanks anyway )
Top comments(6)

for sample, in Laravel 5.4 you can auto routing using the "resource" method. in my conception of a real "automatic REST routing" is possible do the same without use the "resource" method.

Looks like this is what you need -github.com/alexdodonov/mezon-crud-...
For further actions, you may consider blocking this person and/orreporting abuse