domainflow / http
A lightweight PSR-7/15 HTTP kernel, routing, endpoint dispatch, and problem-details package for DomainFlow applications.
Requires
- php: ^8.4
- phpstan/phpdoc-parser: ^2.0
- psr/container: ^2.0
- psr/http-factory: ^1.1
- psr/http-message: ^2.0
- psr/http-server-handler: ^1.0
- psr/http-server-middleware: ^1.0
- relay/relay: ^3.0
- symfony/routing: ^7.4.12 || ^8.0.12
- symfony/type-info: ^7.4.9 || ^8.0.9
Requires (Dev)
- domainflow/core: ^0.2.0
- friendsofphp/php-cs-fixer: ^3.95
- nikic/php-parser: ^5.7
- nyholm/psr7: ^1.8
- phpstan/phpstan: ^2.2
- phpstan/phpstan-deprecation-rules: ^2.0
- phpunit/phpunit: ^13.0
- symfony/phpunit-bridge: ^8.0
Suggests
- domainflow/core: Registers the optional DomainFlow service-provider bridge.
- laminas/laminas-httphandlerrunner: Emits PSR-7 responses in a traditional PHP SAPI runtime.
- nyholm/psr7: Provides PSR-7 and PSR-17 implementations for applications.
- nyholm/psr7-server: Creates a PSR-7 server request from PHP globals.
- symfony/serializer: Can back a custom request hydrator for complex polymorphic DTOs.
Provides
None
Conflicts
None
Replaces
None
This package is auto-updated.
Last update: 2026-08-30 15:44:25 UTC
README
DomainFlow HTTP is a small PSR-based HTTP entry point for DomainFlow applications. It routes PSR-7 server requests to typed invokable endpoints and provides request hydration, endpoint dispatch, JSON responses, Problem Details, compiled routing, and an optional DomainFlow Core bootstrap adapter.
The package keeps application and domain code independent of Symfony HttpFoundation, a concrete PSR-7 implementation, and a full-stack framework.
Requirements
- PHP 8.4 or later; tested on PHP 8.4 and PHP 8.5
- PSR-7 message and PSR-17 factory implementations supplied by the application
- A PSR-11 container when using the included
Psr11EndpointResolver
Symfony Routing and Relay are internal implementation dependencies. Concrete PSR-7 implementations and SAPI emitters remain application choices.
Installation
composer require domainflow/http
The optional Core bridge is available when domainflow/core is installed. The
library itself does not require DomainFlow Core at runtime.
Basic composition
Declare an endpoint as an invokable class with a route attribute:
use DomainFlow\Http\Attribute\Route; #[Route(method: 'GET', path: '/hello/{name}', name: 'hello')] final class HelloEndpoint { public function __invoke(HelloRequest $request): array { return ['message' => 'Hello, ' . $request->name . '!']; } } final readonly class HelloRequest { public function __construct(public string $name) { } }
Routing and request input
Router::match() returns a RouteMatch whose routeParameters contain every
application placeholder captured by the route. This includes placeholders from
both the URI path and the host; internal routing metadata is not exposed:
#[Route(
method: 'GET',
path: '/reports/{reportId}',
host: '{tenant}.api.example.test',
)]
final class TenantReportEndpoint
{
public function __invoke(): void
{
}
}
// https://acme.api.example.test/reports/42
// routeParameters: ['reportId' => '42', 'tenant' => 'acme']
Request hydration combines JSON body fields, query parameters, and route parameters. Query parameters override body fields, and route parameters have the highest precedence so a client cannot replace a value captured by the matched path or host.
Router::generate() always returns an origin-less URI reference such as
/reports/42. The scheme and host are omitted even when the route constrains
them; applications that need an absolute URI remain responsible for supplying
the origin.
Runtime implementations
The package deliberately does not choose a concrete PSR implementation or SAPI
emitter. A minimal application-owned composition is available in
examples/runtime. It uses Nyholm PSR-7 and Laminas'
HTTP handler runner:
cd examples/runtime
composer install
php -S 127.0.0.1:8080 -t public public/index.php
Then request the example endpoint:
curl http://127.0.0.1:8080/hello/Ada
# {"message":"Hello, Ada!"}
DomainFlow Core
DomainFlow\Http\Bridge\DomainFlowCore\HttpServiceProvider registers the
HTTP kernel and default ports during Core bootstrap. Existing application
routers, hydrators, endpoint adapters, problem mappers, and PSR factories remain
application-owned. Core's callable middleware pipeline is not merged into the
PSR-15 request pipeline.
Development
composer test-all composer phpstan composer lint composer quality
The package targets PHP 8.4 and 8.5, PHPStan level 10, strict formatting, dependency auditing, and full reachable-source line coverage.
License
MIT license.