Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Cover image for New PHP framework for creating microservices
alexdodonov
alexdodonov

Posted on • Edited on

     

New PHP framework for creating microservices

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
Enter fullscreen modeExit fullscreen mode

Then include autoload.php

require_once(autoload.php');
Enter fullscreen modeExit fullscreen mode

And the first class will look like this:

classTodoServiceextends\Mezon\Service\ServiceBaseimplements\Mezon\Service\ServiceBaseLogicInterface{/* class body */}
Enter fullscreen modeExit fullscreen mode

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!');}
Enter fullscreen modeExit fullscreen mode

And then launch it:

\Mezon\Service\Service::start(TodoService::class);
Enter fullscreen modeExit fullscreen mode

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);
Enter fullscreen modeExit fullscreen mode

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);
Enter fullscreen modeExit fullscreen mode

You may notice that we have created separate class with our logic:

classTodoLogicextends\Mezon\Service\ServiceBaseLogic
Enter fullscreen modeExit fullscreen mode

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);
Enter fullscreen modeExit fullscreen mode

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]);
Enter fullscreen modeExit fullscreen mode

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:

Twitter
Mezon Framework

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)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
hackergaucho profile image
Hacker Gaucho
back-end (php)
  • Joined
• Edited on• Edited

yourrouter is very similar toKlein, why don't you use it? have you ever thought about making an automatic routing REST system?

CollapseExpand
 
hackergaucho profile image
Hacker Gaucho
back-end (php)
  • Joined

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.

CollapseExpand
 
alexdodonov profile image
alexdodonov
PHP developer
  • Location
    Russia
  • Work
    Alex at Freelance
  • Joined

I shall dig into it. Stay tuned )

CollapseExpand
 
alexdodonov profile image
alexdodonov
PHP developer
  • Location
    Russia
  • Work
    Alex at Freelance
  • Joined

Looks like this is what you need -github.com/alexdodonov/mezon-crud-...

CollapseExpand
 
alexdodonov profile image
alexdodonov
PHP developer
  • Location
    Russia
  • Work
    Alex at Freelance
  • Joined

What do you mean "automatic REST routing"?

CollapseExpand
 
alexdodonov profile image
alexdodonov
PHP developer
  • Location
    Russia
  • Work
    Alex at Freelance
  • Joined

Any comments people? )

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

PHP developer
  • Location
    Russia
  • Work
    Alex at Freelance
  • Joined

More fromalexdodonov

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp