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

sabre/http

sabre/http is a lightweight PHP toolkit for working with HTTP requests and responses. It wraps superglobals and output functions into extendable, mockable Request/Response objects, with SAPI helpers to create a request and support dependency-injected handlers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require sabre/http:~5.0.0
    

    Add to composer.json under require.

  2. First Use Case:

    • Request Handling:
      use Sabre\HTTP\Sapi;
      $request = Sapi::getRequest(); // Initialize once (e.g., in a service provider)
      
    • Response Creation:
      use Sabre\HTTP\Response;
      $response = new Response();
      $response->setStatus(200);
      $response->setBody('Hello, World!');
      Sapi::sendResponse($response); // Send once (e.g., in middleware)
      
  3. Where to Look First:

    • API Docs: Focus on RequestInterface and ResponseInterface.
    • Examples: Check examples/ in the repo for practical use cases (e.g., reverseproxy.php, asyncclient.php).
    • Decorator Pattern: Use RequestDecorator/ResponseDecorator for extending functionality without modifying core classes.

Implementation Patterns

Core Workflows

  1. Request Lifecycle:

    • Dependency Injection: Pass RequestInterface to services/middleware.
      public function handle(RequestInterface $request) {
          $method = $request->getMethod();
          $path = $request->getPath();
          // Logic...
      }
      
    • Query/Post Data:
      $query = $request->getQueryParameters();
      $post = $request->getPostData();
      
  2. Response Handling:

    • Streaming Responses:
      $response->setBody(fopen('large-file.txt', 'r'));
      
    • Headers:
      $response->setHeader('Content-Type', 'application/json');
      $response->addHeaders(['Cache-Control' => 'no-store']);
      
  3. HTTP Client:

    • Synchronous Requests:
      $client = new \Sabre\HTTP\Client();
      $response = $client->send($request);
      
    • Asynchronous Requests:
      $client->sendAsync($request, function($response) {
          // Handle success
      }, function($error) {
          // Handle error
      });
      $client->wait(); // Block until all requests complete
      
  4. Decorators for Extensibility:

    • Request Decorator:
      class AuthRequest extends \Sabre\HTTP\RequestDecorator {
          public function getUser() {
              return $this->getHeader('X-User-ID');
          }
      }
      $request = new AuthRequest(Sapi::getRequest());
      
    • Response Decorator:
      class LoggingResponse extends \Sabre\HTTP\ResponseDecorator {
          public function __construct(\Sabre\HTTP\ResponseInterface $response) {
              parent::__construct($response);
              // Log response before sending
          }
      }
      
  5. Reverse Proxy:

    • Proxy Logic:
      $request = Sapi::getRequest();
      $request->setBaseUrl('/proxy/');
      $proxyRequest = clone $request;
      $proxyRequest->setUrl('https://target.com' . $request->getPath());
      $response = $client->send($proxyRequest);
      Sapi::sendResponse($response);
      

Integration Tips

  • Laravel Middleware: Use Sapi::getRequest() in middleware to access the request early:
    public function handle($request, Closure $next) {
        $sabreRequest = Sapi::getRequest();
        // Modify or log $sabreRequest
        return $next($request);
    }
    
  • Testing: Mock RequestInterface/ResponseInterface for unit tests:
    $mockRequest = $this->createMock(RequestInterface::class);
    $mockRequest->method('getMethod')->willReturn('GET');
    
  • Event-Driven Clients: Attach event listeners to the client for retries/headers:
    $client->on('error:401', function($request, $response, &$retry) {
        $request->setHeader('Authorization', 'Bearer ' . $this->getToken());
        $retry = true;
    });
    

Gotchas and Tips

Pitfalls

  1. Double Initialization:

    • Issue: Calling Sapi::getRequest() multiple times may return inconsistent results (e.g., $_POST modified).
    • Fix: Initialize the request once (e.g., in a service provider) and pass it via DI.
  2. Stream Consumption:

    • Issue: getBodyAsString() consumes the stream, making subsequent reads empty.
    • Fix: Store the string or rewind the stream if possible:
      $body = $request->getBodyAsString();
      // OR
      $stream = $request->getBodyAsStream();
      rewind($stream);
      
  3. Header Case Sensitivity:

    • Issue: Headers are case-insensitive in HTTP but getHeader()/removeHeader() treat names case-sensitively.
    • Fix: Normalize headers (e.g., strtolower()) when comparing.
  4. Async Client Memory Leaks:

    • Issue: Forgetting $client->wait() can leave pending requests consuming resources.
    • Fix: Always call wait() or use a queue system for long-running async tasks.
  5. Base URL Mismatches:

    • Issue: getPath() throws LogicException if the path is outside the base URL.
    • Fix: Ensure setBaseUrl() matches your application’s routing structure (e.g., /api/v1).

Debugging Tips

  1. Inspect Headers/Body:
    var_dump($request->getHeaders());
    echo $request->getBodyAsString();
    
  2. Check HTTP Version:
    • Defaults to 1.1. Explicitly set if needed:
      $request->setHttpVersion('1.0');
      
  3. Validate URLs:
    • Use filter_var() to sanitize URLs before passing to setUrl():
      $url = filter_var($url, FILTER_VALIDATE_URL);
      

Extension Points

  1. Custom Request/Response Classes:
    • Extend RequestDecorator/ResponseDecorator to add domain-specific methods:
      class ApiRequest extends RequestDecorator {
          public function getApiVersion() {
              return $this->getHeader('X-API-Version') ?: 'v1';
          }
      }
      
  2. Override SAPI Factory:
    • For testing, replace Sapi::getRequest() with a custom factory:
      Sapi::setRequestFactory(function() {
          return new MockRequest();
      });
      
  3. Middleware for Decorators:
    • Wrap requests/responses in decorators in Laravel middleware:
      public function handle($request, Closure $next) {
          $request = new AuthRequest(Sapi::getRequest());
          $response = $next($request);
          return new LoggingResponse($response);
      }
      
  4. Event-Driven Extensions:
    • Use the client’s events to add cross-cutting concerns (e.g., logging, retries):
      $client->on('afterRequest', function($request, $response) {
          Log::info('Request to ' . $request->getUrl() . ' responded with ' . $response->getStatus());
      });
      

Config Quirks

  1. PHP Version Compatibility:
    • Ensure your PHP version matches the package’s requirements (e.g., ~5.0.0 needs PHP 7.4+).
    • Use sabre/http:^4.2 for PHP 5.4 support if needed.
  2. Stream Handling:
    • php://input may not be available in all SAPIs (e.g., cli). Use $HTTP_RAW_POST_DATA as a fallback.
  3. Default Headers:
    • Some headers (e.g., Host) are auto-populated by Sapi::getRequest(). Avoid manually setting them unless necessary.

Performance Tips

  1. Reuse Request/Response Objects:
    • Decorators add minimal overhead. Reuse the base Request/Response objects where possible.
  2. Async Batch Processing:
    • For bulk requests, use sendAsync() with a callback to avoid blocking:
      for ($i = 0; $i < 1000; $i++) {
          $client->sendAsync($request, function($response) {
              // Process response non-blockingly
          });
      }
      $client->wait(); // Optional if using a queue
      
  3. Stream Large Responses:
    • Avoid loading large responses into memory:
      $response->setBody(fopen('large-file.zip', 'r
      
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope