# The Basis for building HTTP applications
The httpsoft/http-basis package is a simple and fast HTTP microframework implementing PHP standards recommendations:
- PSR-3 Logger.
- PSR-7 HTTP Message.
- PSR-11 Container.
- PSR-12 Coding Style.
- PSR-15 HTTP Server.
- PSR-17 HTTP Factories.
Package dependencies:
- HttpSoft\Cookie — provides convenient cookie management.
- HttpSoft\Emitter — emits HTTP responses to the client.
- HttpSoft\ErrorHandler — listens, handles and generates errors.
- HttpSoft\Message — strictly implements PSR-7 and PSR-17.
- HttpSoft\Response — adds custom HTTP responses.
- HttpSoft\Router — provides convenient routing management HTTP requests.
- HttpSoft\Runner — runs a server request, builds middleware pipelines, and returns a response.
- HttpSoft\ServerRequest — allows you to easily and flexibly create objects of the server requests and uploaded files.
This package requires PHP version 7.4 or later.
# Building an HTTP Application
There are two ways to build an HTTP application:
- Use the ready-made application template (httpsoft/http-app).
- Create your own application template. See below for how to do this.
# Package installation
It's recommended that you use Composer to install.
composer require httpsoft/http-basis
# Dependency injection
You can use any container that implements the 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(),
]);
This example uses dependencies for HTTP responses in JSON format that are used in the REST API. To render individual templates, you need to install any template engine and implement the HttpSoft\Basis\TemplateRendererInterface.
# Setup and run the application
Creating an application object.
$app = $container->get(HttpSoft\Basis\Application::class);
Setup middleware pipeline.
$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');
// Any custom middleware.
$app->pipe(HttpSoft\Cookie\CookieSendMiddleware::class);
$app->pipe(HttpSoft\Router\Middleware\RouteDispatchMiddleware::class);
Add routes.
$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+'])
;
Run application.
$app->run(HttpSoft\ServerRequest\ServerRequestCreator::create());
You may quickly test this using the built-in PHP server.
php -S 0.0.0.0:8080 -t public/
# Route handling
The example of adding routes uses fictitious class names (HomeHandler
, ListHandler
, etc.) as handlers. This approach allows you to organize the processing of each route in a separate class. These classes implement the Psr\Http\Server\RequestHandlerInterface, read more about handlers, see in 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']);
}
}
Handler objects will be created through the container, so they can accept dependencies in the constructor.
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()));
}
}
# Error handling
The HttpSoft\ErrorHandler\ErrorHandlerMiddleware is responsible for error handling.
This package contains two response generators and one error listener, see details in HttpSoft\Basis\ErrorHandler.
Additionally, two request handlers have been created that return a 404
response, see details in HttpSoft\Basis\Handler.
Added some HTTP exceptions for convenience, see details in HttpSoft\Basis\Exception.
If this is not enough for you, you can easily add your own solutions and any additional functionality.