# Основа для построения HTTP-приложений

Пакет httpsoft/http-basis является простым и быстрый HTTP-микрофреймворком, реализующим рекомендации стандартов PHP:

Зависимости пакета:

  • HttpSoft\Cookie — обеспечивает удобное управление куками.
  • HttpSoft\Emitter — отправляет HTTP-ответы клиенту.
  • HttpSoft\ErrorHandler — слушает, обрабатывает и генерирует ошибки.
  • HttpSoft\Message — строго реализует PSR-7 и PSR-17.
  • HttpSoft\Response — добавляет пользовательские HTTP-ответы.
  • HttpSoft\Router — обеспечивает удобное управление маршрутизацией HTTP-запросов.
  • HttpSoft\Runner — запускает серверный запрос, строит конвейеры посредников и отдает ответ.
  • HttpSoft\ServerRequest — позволяет легко и гибко создавать объекты серверных запросов и загружаемых файлов.

Для этого пакета требуется PHP версии 7.4 или более поздней.

# Построение HTTP-приложения

Построить HTTP-приложение можно двумя способами:

# Установка пакета

Для установки рекомендуется использовать Composer.

composer require httpsoft/http-basis

# Внедрение зависимостей

Вы можете использовать любой контейнер, реализующий Psr\Container\ContainerInterface.

/**
 * @var Psr\Container\ContainerInterface $container
 */

$container = new Container([
    'debug' => true,
    HttpSoft\Basis\Application::class => function (ContainerInterface $container) {
        return new HttpSoft\Basis\Application(
            $container->get(HttpSoft\Router\RouteCollector::class),
            $container->get(HttpSoft\Emitter\EmitterInterface::class),
            $container->get(HttpSoft\Runner\MiddlewarePipelineInterface::class),
            $container->get(HttpSoft\Runner\MiddlewareResolverInterface::class),
            new HttpSoft\Basis\Handler\NotFoundJsonHandler($container->get('debug'))
        );
    },
    HttpSoft\Emitter\EmitterInterface::class => fn() => new HttpSoft\Emitter\SapiEmitter(),
    HttpSoft\Router\RouteCollector::class => fn() => new HttpSoft\Router\RouteCollector(),
    HttpSoft\Runner\MiddlewarePipelineInterface::class => fn() => new HttpSoft\Runner\MiddlewarePipeline(),
    HttpSoft\Runner\MiddlewareResolverInterface::class => function (ContainerInterface $container) {
        return new HttpSoft\Runner\MiddlewareResolver($container);
    },
    HttpSoft\ErrorHandler\ErrorHandlerMiddleware::class => function (ContainerInterface $container) {
        return new HttpSoft\ErrorHandler\ErrorHandlerMiddleware(
            new HttpSoft\Basis\ErrorHandler\ErrorJsonResponseGenerator($container->get('debug'))
        );
    },
    HttpSoft\Cookie\CookieManagerInterface::class => fn() => new HttpSoft\Cookie\CookieManager(),
    Psr\Http\Message\ResponseFactoryInterface::class => fn() => new HttpSoft\Message\ResponseFactory(),
]);

В данном примере используются зависимости для HTTP-ответов в JSON-формате, которые используются в REST API. Для рендеринга отдельных шаблонов нужно установить любой шаблонизатор и реализовать HttpSoft\Basis\TemplateRendererInterface.

# Настройка и запуск приложения

Создание объекта приложения.

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

Настройка конвейера посредников.

$app->pipe(HttpSoft\ErrorHandler\ErrorHandlerMiddleware::class);
$app->pipe(HttpSoft\Basis\Middleware\BodyParamsMiddleware::class);
$app->pipe(HttpSoft\Basis\Middleware\ContentLengthMiddleware::class);
$app->pipe(HttpSoft\Router\Middleware\RouteMatchMiddleware::class);
$app->pipe($adminMiddleware, '/admin');
// Любые пользовательские посредники.
$app->pipe(HttpSoft\Cookie\CookieSendMiddleware::class);
$app->pipe(HttpSoft\Router\Middleware\RouteDispatchMiddleware::class);

Добавление маршрутов.

$app->get('home', '/', HomeHandler::class);
$app->get('list', '/list{[page]}', ListHandler::class)->tokens(['page' => '\d+']);
$app->get('view', '/view/{slug}', ViewHandler::class)->tokens(['slug' => '[\w-]+']);
$app->delete('delete', '/delete/{id}', DeleteHandler::class)->tokens(['id' => '\d+']);
$app->add('edit', '/(create|update)/{id}', EditHandler::class, ['GET', 'POST'])
    ->tokens(['id' => '\d+'])
;

Запуск приложения.

$app->run(HttpSoft\ServerRequest\ServerRequestCreator::create());

Вы можете быстро протестировать это с помощью встроенного PHP-сервера.

php -S 0.0.0.0:8080 -t public/

# Обработка маршрутов

В примере добавления маршрутов в качестве обработчиков используются вымышленные имена классов (HomeHandler, ListHandler и т.д.). Такой подход позволяет организовывать обработку каждого маршрута в отдельном классе. Эти классы реализуют Psr\Http\Server\RequestHandlerInterface, подробнее об обработчиках смотрите в HttpSoft\Runner\MiddlewareResolver.

use HttpSoft\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class HomeHandler implements RequestHandlerInterface
{
    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return new JsonResponse(['name' => 'HomeAction']);
    }
}

Объекты обработчиков будут созданы через контейнер, поэтому они могут принимать зависимости в конструкторе.

use HttpSoft\Basis\Response\PrepareJsonDataTrait;
use HttpSoft\Response\JsonResponse;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;

final class ListHandler implements RequestHandlerInterface
{
    use PrepareJsonDataTrait;

    private Repository $repository;

    public function __construct(Repository $repository)
    {
        $this->repository = $repository;
    }

    public function handle(ServerRequestInterface $request): ResponseInterface
    {
        return new JsonResponse($this->prepareJsonData($this->repository->getAll()));
    }
}

# Обработка ошибок

За обработку ошибок отвечает HttpSoft\ErrorHandler\ErrorHandlerMiddleware.

Данный пакет содержит два генератора ответов и один слушатель ошибок, смотрите подробнее в HttpSoft\Basis\ErrorHandler.

Дополнительно созданы два обработчика запросов, которые возвращают ответ с 404 ошибкой, смотрите подробнее в HttpSoft\Basis\Handler.

Для удобства добавлены несколько HTTP-исключений, смотрите подробнее в HttpSoft\Basis\Exception.

Если вам этого мало, вы легко можете добавить собственные решения и любой дополнительный функционал.