by Enrico Zimuel
Principal Software Engineer @ Elastic
PHP Conference Brazil, 7th December 2019
|
...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
- Martin Fowler
Source: Introduction to microservices
Source: Introduction to microservices
Global variables:
// Returns an empty array if not found:
$header = $request->getHeader('Accept');
// Testing an header
if ($request->hasHeader('Accept')) {
/* ... */
}
// Get query string parameters
$query = $request->getQueryParams();
pecl install swoole
use Swoole\Http\Server;
$http = new Server("127.0.0.1", 9501);
$http->on("start", function ($server) {
echo "Started at http://127.0.0.1:9501\n";
});
$http->on("request", function ($request, $response) {
$response->header("Content-Type", "text/plain");
$response->end("Hello World\n");
});
$http->start();
Test: 16K req/sec on CPU i5-2500, 16 GB RAM, PHP 7.2.12, Swoole 4.2.9
A function that gets a request and generates a response
function ($request)
{
// do something with $request
return $response;
}
function ($request, callable $delegate)
{
// delegating $request to another middleware
$response = $delegate($request);
return $response;
}
function ($request, callable $delegate) use ($cache)
{
if ($cache->has($request)) {
return $cache->get($request);
}
$response = $delegate($request);
$cache->set($request, $response);
return $response;
}
Common interfaces for HTTP server request handlers and HTTP server middleware components that use HTTP messages as described by PSR-7
$app->get('/api/ping', function ($request) {
return JsonResponse(['ack' => time()])
});
// or implement a RequestHandlerInterface
$app->get('/api/ping', App\Handler\PingHandler::class);
namespace App\Handler;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response\JsonResponse;
class PingHandler implements RequestHandlerInterface
{
public function handle(
ServerRequestInterface $request
) : ResponseInterface {
return new JsonResponse(['ack' => time()]);
}
}
$app->route('/api/users[/{id}]', [
Authentication\AuthenticationMiddleware::class,
Authorization\AuthorizationMiddleware::class,
Api\Action\UserAction::class
], ['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');
Install:
composer require zendframework/zend-expressive-swoole
Usage:
vendor/bin/zend-expressive-swoole start
Open your browser at localhost:8080
Run a web application from CLI
Simplify the deploy (only PHP no web server)
2-4x faster than Nginx and Apache
Req/sec (mean) | |
Nginx | 1418.23 |
Apache | 1915.62 |
Swoole | 4864.34 |
Testing environment:
Ubuntu 18.04, Expressive Skeleton 3.2.3, PHP 7.2.12, Nginx 1.14 + FPM,
Apache 2.4.29 + mod_php, Swoole 4.2.9, CPU i5-2500, 16 GB RAM, HD SSD
Using elastic/elasticsearch-php:
use Elasticsearch\ClientBuilder;
$client = ClientBuilder::create()->build();
$params = [
'index' => 'my_index',
'type' => 'my_type',
'id' => 'my_id',
'body' => ['testField' => 'abc']
];
$response = $client->index($params);
print_r($response);
Your window into the Elastic Stack
Detect the anomalies hiding in your Elasticsearch data
Follow me: @ezimuel