Speed up web APIs with
Expressive and Swoole

by Enrico Zimuel
Senior Software Engineer
Rogue Wave Software (USA)

phpDay 2018, Verona (Italy), 12th May

About me


The PHP framework for middleware applications

  • PSR-7 support (using zend-diactoros)
  • PSR-15 support
  • Piping workflow (using zend-stratigility)
  • Features: routing, dependency injection, templating, error handling
  • Last release 3.0.6, 16th April 2018

A basic web API

use Zend\Diactoros\Response\JsonResponse;
use Zend\Expressive\Application;

$container = require 'config/container.php';

$app = $container->get(Application::class);

$app->pipe('/api/ping', function($request) {
    return new JsonResponse(['ack' => time()]);
// or $app->pipe('/api/ping', \App\Handler\PingHandler::class);

Request Handler

use Psr\Http\Message\ResponseInterface; // PSR-7
use Psr\Http\Message\ServerRequestInterface; // PSR-7
use Psr\Http\Server\RequestHandlerInterface; // PSR-15
use Zend\Diactoros\Response\JsonResponse;

class PingHandler implements RequestHandlerInterface
    public function handle(
        ServerRequestInterface $request
    ) : ResponseInterface
        return new JsonResponse(['ack' => time()]);

Middleware Class

use Psr\Http\Message\ResponseInterface; // PSR-7
use Psr\Http\Message\ServerRequestInterface; // PSR-7
use Psr\Http\Server\MiddlewareInterface; // PSR-15
use Psr\Http\Server\RequestHandlerInterface; // PSR-15

class AuthMiddleware implements MiddlewareInterface
    // ...
    public function process(
        ServerRequestInterface $request,
        RequestHandlerInterface $handler
    ) : ResponseInterface
        $user = $this->auth->authenticate($request);
        if (null !== $user) {
            return $handler->handle($request->withAttribute(
        return $this->auth->unauthorizedResponse($request);

Example: Routing REST API

$app->route('/api/users[/{id}]', [
], ['GET', 'POST', 'PATCH', 'DELETE'], 'api.users');

// or route each HTTP method
$app->get('/api/users[/{id}]', ..., 'api.users.get');
$app->post('/api/users', ..., 'api.users.post');
$app->patch('/api/users/{id}', ..., 'api.users.patch');
$app->delete('/api/users/{id}', ..., 'api.users.delete');

Quick start

You can start using Expressive with composer:

composer create-project zendframework/zend-expressive-skeleton <dir>

Libraries for API

REST example



  • Swoole is an async programming framework for PHP 7
  • PHP extension, install:
    pecl install swoole
  • Released under Apache license 2.0
  • More info at swoole.co.uk


  • Event-driven, asynchronous programming for PHP
  • Async TCP / UDP / HTTP / Websocket / HTTP2 client/server side API
  • IPv4 / IPv6 / Unixsocket / TCP/ UDP and SSL / TLS support
  • High performance, scalable, support C1000K
  • Fast serializer / unserializer
  • Milliseconds task scheduler

HTTP Server

$http = new swoole_http_server("", 9501);

$http->on("start", function ($server) {
    echo "Started at\n";

$http->on("request", function ($request, $response) {
    $response->header("Content-Type", "text/plain");
    $response->end("Hello World\n");


Expressive with Swoole

Use wshafer/swoole-expressive library


composer require wshafer/swoole-expressive:dev-master


vendor/bin/swoole-expressive --host= --port=8080

HTTP Server for PSR-7

use Swoole\Http\Request;
use Swoole\Http\Response

$http = new swoole_http_server($host, $port);
    function (Request $request, Response $response) use
        ($app, $psr7Request, $swooleResponse) {
        $psrResponse = $app->handle($psr7Request->from($request));
        $swooleResponse->fromPsr7($psrResponse, $response);

Swoole vs. nginx vs. Apache

Benchmark results

Expressive with Swoole runs 4x faster than nginx and Apache (source)


Rate this talk at joind.in/talk/bef90

Creative Commons License
This work is licensed under a
Creative Commons Attribution-ShareAlike 3.0 Unported License.
I used reveal.js to make this presentation.