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 Message Laravel Package

sunrise/http-message

Sunrise HTTP Message provides a PSR-7 HTTP message implementation with PSR-17 factories, aligned with RFC-7230. Use it to create and work with requests, responses, URIs, streams, and uploaded files in a standards-compliant way.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require sunrise/http-message
    

    Ensure your composer.json has PHP ≥7.4 (recommended: 8.1+).

  2. First Use Case: Create a PSR-7 request/response with built-in factories:

    use Sunrise\HttpMessage\{RequestFactory, ResponseFactory};
    
    $request = RequestFactory::createJsonRequest('GET', '/api/users', ['id' => 1]);
    $response = ResponseFactory::createJsonResponse(['status' => 'success']);
    
  3. Key Classes to Explore:

    • RequestFactory/ResponseFactory: Convenience methods for common HTTP types (JSON, HTML, URL-encoded).
    • Stream: Core stream handling (e.g., writeStream(), LineStream).
    • FileStream: For file uploads/downloads (check getFilename()).
  4. Documentation: Start with Sunrise’s official docs for API references and examples.


Implementation Patterns

Core Workflows

1. Request/Response Creation

  • JSON APIs:
    $request = RequestFactory::createJsonRequest('POST', '/data', ['key' => 'value']);
    $response = ResponseFactory::createJsonResponse($data, 201);
    
  • Form Data:
    $request = RequestFactory::createUrlEncodedRequest('POST', '/login', [
        'email' => 'user@example.com',
        'password' => 'secret'
    ]);
    

2. Stream Handling

  • File Uploads:
    $fileStream = new FileStream('/path/to/file.txt');
    $request = RequestFactory::createRequest('POST', '/upload')
        ->withBody($fileStream);
    
  • Chunked Uploads:
    $stream = new Stream();
    $stream->writeStream($sourceStream, 1024); // Write in 1KB chunks
    

3. Middleware Integration

Use with Laravel’s middleware pipeline (e.g., HandlePsr7Request):

use Sunrise\HttpMessage\{RequestInterface, ResponseInterface};

public function handle(RequestInterface $request, Closure $next): ResponseInterface {
    // Modify request/response
    return $next($request)->withHeader('X-Processed', 'true');
}

4. Dependency Injection

Register factories in Laravel’s AppServiceProvider:

public function register(): void {
    $this->app->singleton(RequestFactory::class, fn() => new RequestFactory());
    $this->app->singleton(ResponseFactory::class, fn() => new ResponseFactory());
}

5. Testing

Mock requests/responses in PHPUnit:

$mockRequest = $this->createMock(RequestInterface::class);
$mockRequest->method('getMethod')->willReturn('GET');

Integration Tips

Laravel-Specific

  • Replace Illuminate\Http\Request: Extend Sunrise\HttpMessage\Request for custom logic:
    class CustomRequest extends Request {
        public function getCustomHeader(): string {
            return $this->getHeaderLine('X-Custom');
        }
    }
    
  • PSR-7 Middleware: Use Psr7Middleware facade to wrap Laravel middleware:
    use Sunrise\HttpMessage\Psr7Middleware;
    
    $middleware = Psr7Middleware::wrap($laravelMiddleware);
    

Performance

  • Reuse Streams: Avoid recreating streams for repeated operations (e.g., file uploads).
  • Memory Efficiency: Use LineStream for large text files to process line-by-line:
    $lineStream = new LineStream($fileStream);
    foreach ($lineStream as $line) {
        // Process line
    }
    

Extending Functionality

  • Custom Factories: Extend RequestFactory/ResponseFactory for domain-specific defaults:
    class ApiRequestFactory extends RequestFactory {
        public function createAuthRequest(string $method, string $uri, array $data): RequestInterface {
            return $this->createRequest($method, $uri)
                ->withHeader('Authorization', 'Bearer token')
                ->withBody($this->createJsonBody($data));
        }
    }
    

Gotchas and Tips

Pitfalls

1. Header Case Sensitivity

  • Headers are case-insensitive per RFC-7230, but getHeader()/getHeaderLine() may return original casing.
  • Use withAddedHeader() for consistency:
    $request->withAddedHeader('content-type', 'application/json'); // Normalized
    

2. Stream Detachment

  • Detached streams (e.g., after detach()) cannot be reused. Always clone or reattach:
    $stream = $request->getBody();
    $clonedStream = clone $stream; // Safe to use later
    

3. PHP 8.4+ Quirks

  • Some older dependencies may conflict. Pin sunrise/http-header to ^3.0 if issues arise.

4. JSON Validation

  • createJsonResponse() throws JsonException on invalid data. Validate early:
    try {
        $response = ResponseFactory::createJsonResponse($data);
    } catch (JsonException $e) {
        abort(500, 'Invalid JSON data');
    }
    

5. FileStream Limitations

  • getFilename() only works for local files. For uploaded files, use:
    $file = $request->getUploadedFile('file');
    $stream = new FileStream($file->getPathname());
    

Debugging Tips

1. Inspect Headers

Dump raw headers for debugging:

dd($request->getHeaders());

2. Stream Contents

Read stream contents without consuming it:

$stream = $request->getBody();
$contents = $stream->getContents(); // Consumes stream!
// Alternative (non-consuming):
$stream->rewind();
$chunk = $stream->read(1024);

3. Middleware Debugging

Log PSR-7 requests/responses:

public function handle(RequestInterface $request, Closure $next): ResponseInterface {
    \Log::debug('Request:', [
        'method' => $request->getMethod(),
        'uri' => (string) $request->getUri(),
        'headers' => $request->getHeaders()
    ]);
    return $next($request);
}

Extension Points

1. Custom Stream Types

Implement StreamInterface for domain-specific streams (e.g., database blobs):

class DatabaseStream implements StreamInterface {
    public function read(int $length): string {
        return $this->db->fetchBlob($length);
    }
    // ... other methods
}

2. Factory Decorators

Decorate factories to add pre-processing:

class AuthRequestFactory {
    public function __construct(private RequestFactory $factory) {}

    public function create(string $method, string $uri): RequestInterface {
        return $this->factory->createRequest($method, $uri)
            ->withHeader('X-Auth', 'required');
    }
}

3. PSR-15 Middleware

Create reusable middleware for PSR-7:

use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

class LoggingMiddleware implements MiddlewareInterface {
    public function process(RequestInterface $request, RequestHandlerInterface $handler): ResponseInterface {
        // Pre-flight logic
        $response = $handler->handle($request);
        // Post-flight logic
        return $response;
    }
}

4. URI Handling

Combine with sunrise/uri for advanced URI manipulation:

use Sunrise\Uri\Uri;

$uri = Uri::createFromString('/api/users?page=1');
$request = RequestFactory::createRequest('GET', $uri);

Configuration Quirks

  • Default HTTP Version: Set globally via RequestFactory:
    $factory = new RequestFactory();
    $factory->setDefaultHttpVersion('1.1');
    
  • Case-Insensitive Headers: Enable via sunrise/http-header config (if integrated):
    $headerManager = new HeaderManager();
    $headerManager->setCaseInsensitive(true);
    
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