phrity/http
Phrity Http provides small PSR-friendly utilities for HTTP in PHP. Includes an HttpFactory wrapper that combines PSR-17 factories (or auto-configures from a single implementation) and a Serializer that converts PSR-7 requests/responses/messages to raw HTTP strings.
Installation:
composer require phrity/http
Basic HttpFactory Usage:
Integrate with an existing PSR-17 implementation (e.g., Guzzle or Nyholm):
use Phrity\Http\HttpFactory;
use GuzzleHttp\Psr7\HttpFactory as GuzzleHttpFactory;
$guzzleFactory = new GuzzleHttpFactory();
$phrityFactory = HttpFactory::create($guzzleFactory);
$request = $phrityFactory->createRequest('GET', '/api/users');
Serializer for Debugging: Convert PSR-7 messages to raw strings for logging or inspection:
use Phrity\Http\Serializer;
$serializer = new Serializer();
$rawRequest = $serializer->request($request);
logger()->info('Raw HTTP Request:', ['data' => $rawRequest]);
Replace ad-hoc PSR-7 factory usage in API clients with HttpFactory:
// Before: Manual factory usage
$request = new \Nyholm\Psr7\Request('POST', '/endpoint', [
'Content-Type' => 'application/json',
], json_encode(['key' => 'value']));
// After: Unified factory
$factory = HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
$request = $factory->createRequest('POST', '/endpoint', [
'Content-Type' => 'application/json',
], json_encode(['key' => 'value']));
HttpFactory: Source – Focus on the create() method and constructor for integration patterns.Serializer: Source – Check the request(), response(), and message() methods for output format details.Pattern: Centralize PSR-17 factory creation in a service container (e.g., Laravel’s AppServiceProvider).
// app/Providers/AppServiceProvider.php
public function register()
{
$this->app->singleton(HttpFactory::class, function ($app) {
return HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
});
}
Usage in Clients:
$factory = app(HttpFactory::class);
$request = $factory->createRequest('GET', '/users');
Pattern: Log raw HTTP requests/responses in middleware for observability.
// app/Http/Middleware/LogHttp.php
public function handle($request, Closure $next)
{
$serializer = new Serializer();
logger()->debug('Incoming Request', [
'raw' => $serializer->request($request),
]);
$response = $next($request);
logger()->debug('Outgoing Response', [
'raw' => $serializer->response($response),
]);
return $response;
}
Pattern: Generate synthetic PSR-7 messages for unit tests without external dependencies.
// tests/Unit/HttpTest.php
public function test_api_client()
{
$factory = HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
$request = $factory->createRequest('GET', '/test');
$request = $request->withHeader('X-Test', 'true');
$response = $factory->createResponse(200)
->withBody($factory->createStream('{"success": true}'));
// Use in test assertions or mocks
}
nyholm/psr7 or guzzlehttp/psr7 as the underlying factory for HttpFactory:
$factory = HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
Illuminate\Http\Request to use HttpFactory for consistency:
// app/Extensions/HttpFactoryExtension.php
class HttpFactoryExtension
{
public static function createRequest(string $method, string $uri, array $headers = []): \Psr\Http\Message\RequestInterface
{
$factory = HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
return $factory->createRequest($method, $uri, $headers);
}
}
Serializer to format output for specific needs (e.g., JSON):
class JsonSerializer extends \Phrity\Http\Serializer
{
public function request(\Psr\Http\Message\RequestInterface $request): string
{
return json_encode([
'method' => $request->getMethod(),
'uri' => (string) $request->getUri(),
'headers' => $request->getHeaders(),
'body' => (string) $request->getBody(),
]);
}
}
HttpFactory to switch implementations based on environment (e.g., test vs. production):
$factory = config('http.factory') === 'test'
? HttpFactory::create(new \Nyholm\Psr7\HttpFactory())
: HttpFactory::create(new \GuzzleHttp\Psr7\HttpFactory());
HttpFactory throws BadMethodCallException if a required factory (e.g., uploadedFileFactory) is missing.$factory = new HttpFactory(
requestFactory: $requestFactory,
responseFactory: $responseFactory,
// ... other factories
uploadedFileFactory: new class implements UploadedFileFactoryInterface {
public function createUploadedFile(StreamInterface $stream, int $size, int $error, string $name, string $type): UploadedFileInterface
{
return new \Nyholm\Psr7\UploadedFile($stream, $size, $error, $name, $type);
}
}
);
Serializer’s raw output may not match expectations (e.g., no pretty-printing for large payloads).Serializer or pre-process the output:
$raw = $serializer->request($request);
$formatted = preg_replace('/\r?\n/', "\n", $raw); // Normalize line endings
$body = (string) $request->getBody();
if (strlen($body) > 1024) { // Skip large bodies
$serialized = $serializer->request($request->withoutBody());
} else {
$serialized = $serializer->request($request);
}
Illuminate\Http\Request extends Symfony\Component\HttpFoundation\Request, which may not fully align with PSR-7.HttpFactory only for PSR-7-compliant messages or wrap Laravel requests:
$psrRequest = \Nyholm\Psr7\ServerRequest::fromGlobals();
$factory = HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
$request = $factory->createRequest($psrRequest->getMethod(), (string) $psrRequest->getUri());
$factory = new HttpFactory(
requestFactory: new \Nyholm\Psr7\RequestFactory(),
responseFactory: new \Nyholm\Psr7\ResponseFactory(),
// ... other factories
);
logger()->debug('Serializer Output', [
'request' => $serializer->request($request),
'response' => $serializer->response($response),
]);
How can I help you explore Laravel packages today?