Microservices architectural style has rapidly become the de-facto standard for continuously deployed systems and thus, it is widely adopted. Its main characteristics are enlisted in a definition given by Martin Fowler: the microservice architectural style is an approach to developing a single application as a suite of small services, each running in its own process and communicating with lightweight mechanisms, often an HTTP resource API.
Microservices oriented development grants several advantages over monolithic approaches, such as an higher degree of modularity and encapsulation, better scalability and faster development times. However, microservices also bring the typical disadvantages of distributed systems: they are harder to debug, more sensitive to networking issues (latency, link unreliability, etc.) and can be more complex to deploy and maintain without the proper tools.
Nowadays there are several programming languages and technologies especially designed to develop microservices. Moreover, thanks to containers, any language can be used.
At Codemotion Milan 2018, Enrico Zimuel from Rogue Wave Software illustrated how to develop microservices in PHP.
Zimuel is a veteran of PHP development, being an open source contributor of both the Zend framework and the Expressive framework and a senior engineer at Rogue Wave Software (who acquired Zend Technologies a few years ago).
PHP is a well-known and widely adopted technology, mainly used for the development of web applications. It is a modern and continuously evolving programming language and a solid foundation to build application frameworks and libraries with ease, being actively maintained for over 20 years.
The Expressive framework
Based on these assumptions, Zimuel presented Expressive, an application framework based on several Zend modules explicitly designed to create middleware services rapidly.
Expressive is both PSR-7 (via zend-diactoros) and PSR-15 (via zend-stratigility) compliant, supporting several routing libraries (such as Aura and FastRoute) and several dependency injection containers (zend-servicemanager, pimple-interop, aura.di). Moreover, it features a built-in templating system and graceful error handling.
In a nutshell, Expressive allows rapid middleware development, by providing a substantial amount of boilerplate code in a single integrated and elegant solution.
Developing services in Expressive is just a matter of implementing the RequestHandlerInterface in a custom Handler class and providing the code required to handle a particular request. Through the usage of delegates, middleware classes can be linked together. As an example, authentication checks can be implemented in a middleware that is always invoked first for any request. Only when authentication is confirmed, the middleware that handles the request is invoked, otherwise an error is returned.
Creating a new project based on Expressive is also very easy since a custom installer for Composer is available. The installer will create a skeleton project and fetch all the required libraries and components.
Expressive also supports asynchronous programming natively through Swoole. Swoole is a PHP 7 extension library that brings asynchronous and coroutine-based networking communication with high performance. It supports several communication protocols, such as TCP / UDP, HTTP, HTTP2 and WebSockets, supports SSL/TLS natively and has a fast built-in serializer / de-serializer.
Using Swoole built-in HTTP server, it is possible to run an API gateway directly from the CLI, without requiring an extra web server. That means microservices written with Swoole can be deployed with a lightweight container that ships only the PHP interpreter, rather than the usual base images with PHP plus a webserver.
Moreover, several benchmarks have shown how well Swoole performs compared to PHP-FPM, sometimes from two to four times faster. The main reason for this performance increment is the persistence of Swoole worker processes in memory. Applications served with Swoole are often bootstrapped just once, and then kept in memory, while being re-loaded for any request. This can improve performance significantly but may also introduce some side-effects, especially when dealing with global variables. The solution to these issues is to use the Swoole Sandbox mode to isolate the app containers.
Microservices in PHP: conclusions
Developing microservices with PHP can be fun and efficient. The advantages offered by frameworks such as Expressive are obvious, while disadvantages must be carefully evaluated on a project basis. One of the most common disadvantages in using PHP to implement microservices has been latency. Swoole is a great answer to overcome this limitation and deliver high performance PHP-based solutions.