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

hyperf/http-message

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require hyperf/http-message
    

    Ensure your composer.json includes "hyperf/hyperf": "^3.0" as a dependency, as this package is part of the Hyperf ecosystem.

  2. First Use Case:

    • Request/Response Handling:
      use Hyperf\HttpMessage\Stream\SwooleStream;
      use Hyperf\HttpMessage\Uri;
      use Hyperf\HttpMessage\RequestMessage;
      use Hyperf\HttpMessage\ResponseMessage;
      
      // Create a request
      $request = new RequestMessage(
          'GET',
          new Uri('https://example.com/api'),
          ['Host' => 'example.com']
      );
      
      // Create a response
      $response = new ResponseMessage(200, ['Content-Type' => 'application/json']);
      $response->getBody()->write(json_encode(['success' => true]));
      
  3. Key Classes to Explore:

    • RequestMessage: For handling incoming HTTP requests.
    • ResponseMessage: For constructing HTTP responses.
    • Stream\SwooleStream: For stream operations (Swoole-specific).
    • Uri: For URI manipulation.

Implementation Patterns

Core Workflows

1. Request Processing

  • Parsing Requests:
    $request = new RequestMessage(
        $method,
        new Uri($uri),
        $headers,
        $body ?? null
    );
    $method = $request->getMethod(); // GET, POST, etc.
    $uri = $request->getUri();
    $headers = $request->getHeaders();
    $body = $request->getBody()->__toString();
    
  • Query/Path Parameters: Use Uri to parse query strings or path segments:
    $uri = new Uri('/users/{id}?sort=name');
    $pathSegments = $uri->getPathSegments(); // ['users', '{id}']
    $queryParams = $uri->getQueryParams(); // ['sort' => 'name']
    

2. Response Construction

  • Building Responses:
    $response = new ResponseMessage(200, ['X-Custom-Header' => 'value']);
    $response->getBody()->write(json_encode(['data' => 'value']));
    
  • Cookies and Redirects:
    $response->withCookie(new Cookie('token', 'abc123', 3600));
    $response->withHeader('Location', '/new-path')->setStatusCode(302);
    

3. Stream Handling

  • File Uploads/Downloads:
    $stream = new SwooleStream(fopen('file.txt', 'r'));
    $request->getBody()->rewind();
    $request->getBody()->pipeTo($stream); // Stream upload to file
    

4. Middleware Integration

  • Custom Middleware:
    class LogMiddleware
    {
        public function __invoke(RequestMessage $request, callable $next)
        {
            logger()->info('Request:', [
                'method' => $request->getMethod(),
                'uri' => $request->getUri()->__toString(),
            ]);
            return $next($request);
        }
    }
    
    Register in config/middleware.php:
    return [
        \App\Middleware\LogMiddleware::class,
    ];
    

5. Server Request/Response (Swoole Context)

  • Server-Side Usage:
    use Hyperf\HttpServer\Request;
    use Hyperf\HttpServer\Response;
    
    $request = Request::capture();
    $response = new Response();
    $response->json(['message' => 'Hello, Hyperf!']);
    $response->send();
    

Gotchas and Tips

Common Pitfalls

  1. Stream Detachment:

    • Streams (e.g., SwooleStream) must be detached before being passed to non-Swoole contexts (e.g., logging, storage):
      $stream = $request->getBody();
      $detachedStream = $stream->detach(); // Critical for non-Swoole operations
      file_put_contents('log.txt', $detachedStream);
      
  2. Header Case Sensitivity:

    • Headers are case-insensitive but stored as lowercase. Use getHeaderLine() for exact matches:
      $request->hasHeader('content-type'); // Case-insensitive
      $request->getHeaderLine('Content-Type'); // Exact match
      
  3. URI Parsing Quirks:

    • Uri::withQuery() overwrites existing queries. Use Uri::withAddedQuery() to append:
      $uri = (new Uri('/users'))->withAddedQuery('sort', 'name');
      
  4. Body Consumption:

    • HTTP message bodies are streams and can only be read once. Rewind or detach if needed:
      $body = $request->getBody();
      $body->rewind(); // Reset stream pointer
      $content = $body->__toString();
      

Debugging Tips

  1. Inspect Headers/Body:

    logger()->debug('Request Headers:', $request->getHeaders());
    logger()->debug('Request Body:', $request->getBody()->__toString());
    
  2. Validate Responses:

    • Use ResponseMessage::toPsrResponse() to convert to PSR-7 for compatibility checks:
      $psrResponse = $response->toPsrResponse();
      $status = $psrResponse->getStatusCode();
      
  3. Swoole-Specific Issues:

    • If streams behave unexpectedly, ensure:
      • The Swoole event loop is running.
      • Streams are not closed prematurely (e.g., by fclose in PHP).

Extension Points

  1. Custom Stream Adapters:

    • Implement Psr\Http\Message\StreamInterface for non-Swoole streams (e.g., Symfony streams):
      class SymfonyStream implements StreamInterface
      {
          private $symfonyStream;
      
          public function __construct(\Symfony\Component\HttpFoundation\StreamedResponse $stream)
          {
              $this->symfonyStream = $stream->getStream();
          }
      
          // Implement StreamInterface methods...
      }
      
  2. Middleware Decorators:

    • Decorate RequestMessage/ResponseMessage to add cross-cutting concerns:
      class AuthMiddleware
      {
          public function __invoke(RequestMessage $request, callable $next)
          {
              if (!$request->hasHeader('authorization')) {
                  throw new \RuntimeException('Unauthorized');
              }
              return $next($request);
          }
      }
      
  3. PSR-7 Interoperability:

    • Use Hyperf\HttpMessage\Psr7\Psr7Request/Psr7Response for PSR-7 compatibility:
      $psrRequest = new Psr7Request($request);
      $psrResponse = new Psr7Response($response);
      
  4. Performance Optimization:

    • For high-throughput services, reuse RequestMessage/ResponseMessage objects where possible to avoid overhead:
      $requestPool = new ObjectPool(
          fn() => new RequestMessage('GET', new Uri('/')),
          fn(RequestMessage $request) => $request->getBody()->rewind()
      );
      

Configuration Quirks

  1. Default Headers:

    • Hyperf may inject default headers (e.g., Server, Date). Override in config/http.php:
      return [
          'default_headers' => [
              'X-Powered-By' => ['hyperf', 'http-message'],
          ],
      ];
      
  2. Stream Buffers:

    • Swoole streams may buffer data. Disable buffering if needed:
      $stream = new SwooleStream(fopen('file.txt', 'r'), false); // Disable buffering
      
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