Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Http Laravel Package

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.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require phrity/http
    
  2. 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');
    
  3. 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]);
    

First Use Case: Standardizing HTTP Clients

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']));

Where to Look First

  • 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.
  • Tests: Acceptance Tests – Validate edge cases (e.g., missing factories, large payloads).

Implementation Patterns

Workflows

1. Unified HTTP Factory for API Clients

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');

2. Debugging Middleware with Serializer

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;
}

3. Test Doubles for HTTP Messages

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
}

Integration Tips

Laravel-Specific Integrations

  • PSR-7 Adapters: Use nyholm/psr7 or guzzlehttp/psr7 as the underlying factory for HttpFactory:
    $factory = HttpFactory::create(new \Nyholm\Psr7\HttpFactory());
    
  • Illuminate HTTP Bridge: Extend Laravel’s 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 Customization

  • Output Formatting: Extend the 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(),
            ]);
        }
    }
    

Dynamic Factory Composition

  • Conditional Factories: Use 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());
    

Gotchas and Tips

Pitfalls

1. Missing Factory Exceptions

  • Issue: HttpFactory throws BadMethodCallException if a required factory (e.g., uploadedFileFactory) is missing.
  • Fix: Provide all required factories or use a fallback implementation:
    $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);
            }
        }
    );
    

2. Serializer Output Format

  • Issue: The Serializer’s raw output may not match expectations (e.g., no pretty-printing for large payloads).
  • Fix: Extend the Serializer or pre-process the output:
    $raw = $serializer->request($request);
    $formatted = preg_replace('/\r?\n/', "\n", $raw); // Normalize line endings
    

3. Performance with Large Payloads

  • Issue: Serializing large HTTP messages (e.g., file uploads) can consume significant memory.
  • Fix: Stream the output or limit payload size:
    $body = (string) $request->getBody();
    if (strlen($body) > 1024) { // Skip large bodies
        $serialized = $serializer->request($request->withoutBody());
    } else {
        $serialized = $serializer->request($request);
    }
    

4. Laravel-Specific Quirks

  • Issue: Laravel’s Illuminate\Http\Request extends Symfony\Component\HttpFoundation\Request, which may not fully align with PSR-7.
  • Fix: Use 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());
    

Debugging Tips

1. Validate Factory Configuration

  • Ensure all required factories are provided:
    $factory = new HttpFactory(
        requestFactory: new \Nyholm\Psr7\RequestFactory(),
        responseFactory: new \Nyholm\Psr7\ResponseFactory(),
        // ... other factories
    );
    

2. Inspect Serializer Output

  • Log the raw output to verify format:
    logger()->debug('Serializer Output', [
        'request' => $serializer->request($request),
        'response' => $serializer->response($response),
    ]);
    

3. Handle PSR-7 Edge Cases

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor