Skip to content

open-source-contributions/react-framework

 
 

Antidot React Framework

link-packagist Scrutinizer Code Quality type-coverage Code Coverage Build Status

Requirements:

  • PHP ^7.4|^8.0
  • Antidot Framework
  • React Http
  • Ramsey Uuid

Description

This package allows running both common synchronous and modern asynchronous PHP following PSR-15 middleware standard approach.

Install

The preferred way to install this library is using the reactive-antidot-starter project.

composer create-project antidot-fw/reactive-antidot-starter

Reactive Antidot Framework

To install it on a existing Antidot Framework Project installation we need to tweak some configurations and replace or create new index.php file.

composer require antidot-fw/react-framework

Config

  • Disable LaminasRequest Handler Runner
  • Load Antidot React Config Provider after Antidot Framework provider

Example config from starter project

<?php
// config/config.php

declare(strict_types=1);

use Antidot\DevTools\Container\Config\ConfigProvider as DevToolsConfigProvider;
use Antidot\SymfonyConfigTranslator\Container\Config\ConfigAggregator;
use Antidot\Yaml\YamlConfigProvider;
use Laminas\ConfigAggregator\ArrayProvider;
use Laminas\ConfigAggregator\PhpFileProvider;

// To enable or disable caching, set the `ConfigAggregator::ENABLE_CACHE` boolean in
// `config/autoload/local.php`.
$cacheConfig = [
    'config_cache_path' => 'var/cache/config-cache.php',
];

$aggregator = new ConfigAggregator([
    \WShafer\PSR11MonoLog\ConfigProvider::class,
    \Antidot\Event\Container\Config\ConfigProvider::class,
    \Antidot\Logger\Container\Config\ConfigProvider::class,
    \Antidot\Cli\Container\Config\ConfigProvider::class,
    \Antidot\Fast\Router\Container\Config\ConfigProvider::class,
    \Antidot\Container\Config\ConfigProvider::class,
    \Antidot\React\Container\Config\ConfigProvider::class,
    class_exists(DevToolsConfigProvider::class) ? DevToolsConfigProvider::class : fn() => [],
    new PhpFileProvider(realpath(__DIR__).'/services/{{,*.}prod,{,*.}local,{,*.}dev}.php'),
    new YamlConfigProvider(realpath(__DIR__).'/services/{{,*.}prod,{,*.}local,{,*.}dev}.yaml'),
    new ArrayProvider($cacheConfig),
], $cacheConfig['config_cache_path']);

return $aggregator->getMergedConfig();

The create your React Http server

#!/usr/bin/env php
<?php
// public/index.php or everywhere you want to allocate your server

declare(strict_types=1);

use Antidot\Application\Http\Application;
use Antidot\React\PromiseResponse;
use Laminas\Diactoros\Response\HtmlResponse;
use Psr\Http\Message\ServerRequestInterface;
use Ramsey\Uuid\Uuid;
use React\EventLoop\Factory;
use React\Http\Middleware\LimitConcurrentRequestsMiddleware;
use React\Http\Middleware\RequestBodyBufferMiddleware;
use React\Http\Middleware\RequestBodyParserMiddleware;
use React\Http\Middleware\StreamingRequestMiddleware;
use React\Http\Server;
use React\Socket\Server as Socket;
use function React\Promise\resolve;

require 'vendor/autoload.php';

call_user_func(static function () {
    $loop = Factory::create();
    $container = require 'config/container.php';
    $application = $container->get(Application::class);
    (require 'router/middleware.php')($application, $container);
    (require 'router/routes.php')($application, $container);

    $server = new Server(
        $loop,
        new StreamingRequestMiddleware(),
        new LimitConcurrentRequestsMiddleware(100), // 100 concurrent buffering handlers
        new RequestBodyBufferMiddleware(4 * 1024 * 1024), // 4 MiB
        new RequestBodyParserMiddleware(),
        static function (ServerRequestInterface $request) use ($application) {
            try {
                $response = new PromiseResponse(
                    resolve($request)
                        ->then(static fn ($request) => $request->withAttribute('request_id', Uuid::uuid4()->toString()))
                        ->then(static fn ($request) => $application->handle($request))
                );
            } catch (Throwable $exception) {
                if (!empty($e = $exception->getPrevious())) {
                    $exception = $e;
                }

                $response = new HtmlResponse(
                    sprintf(
                        '%s in file %s in line %s.',
                        $exception->getMessage(),
                        $exception->getFile(),
                        $exception->getLine()
                    )
                );
            }

            return resolve($response);
        }
    );

    $server->on('error', function ($err) {
        dump($err);
    });

    $socket = new Socket('0.0.0.0:8080', $loop);
    $server->listen($socket);

    $loop->run();
});

About

No description, website, or topics provided.

Resources

License

Code of conduct

Stars

Watchers

Forks

Packages

No packages published

Languages

  • PHP 100.0%