Use Laravel HTTP Global Middleware to Transparently Modify API Requests

๐Ÿ“– 2 minutes read

Laravel’s Http facade provides globalRequestMiddleware() and globalResponseMiddleware() methods that intercept ALL outgoing HTTP requests made through the facade. This is perfect for transparently modifying third-party API calls without changing application code.

The Problem

You’re using a third-party Laravel package that makes HTTP calls, but you need to:

  • Swap authentication methods (API key โ†’ OAuth)
  • Inject custom headers
  • Log all requests
  • Modify request bodies

…without forking the package or wrapping every HTTP call.

The Solution

Register global middleware in AppServiceProvider::boot():

use Illuminate\Support\Facades\Http;

public function boot()
{
    Http::globalRequestMiddleware(function ($request) {
        // Only modify requests to specific API
        if (str_contains($request->url(), 'api.example.com')) {
            // Swap authentication method
            $apiKey = $request->header('X-API-Key');
            if ($apiKey && str_starts_with($apiKey, 'key-oauth-')) {
                // Remove API key header
                $request->withoutHeader('X-API-Key');
                // Add OAuth Bearer token instead
                $request->withHeader('Authorization', 'Bearer ' . $apiKey);
            }
            
            // Inject custom headers
            $request->withHeaders([
                'User-Agent' => 'MyApp/1.0',
                'X-Custom-Header' => 'value'
            ]);
            
            // Modify request body (for JSON requests)
            if ($request->isJson()) {
                $data = $request->data();
                $data['extra_param'] = 'injected_value';
                $request->withBody(json_encode($data), 'application/json');
            }
        }
        
        return $request;
    });
}

Response Middleware Too

Http::globalResponseMiddleware(function ($response) {
    // Transform response data globally
    if ($response->json('status') === 'legacy_format') {
        return $response->json(['data' => $response->json()]);
    }
    return $response;
});

Why This Matters

Enables transparent API modification without forking packages or wrapping every HTTP call. Perfect for:

  • Authentication adaptation: Add auth headers packages don’t support
  • Logging: Track all outgoing requests in one place
  • Header injection: Add tracking IDs, custom user agents
  • Rate limiting: Add delays globally

This approach operates at the HTTP layer (not application layer), making it transparent to packages that use Http:: internally.

Real-World Example

Adapting a third-party SDK that only supports API key auth, but your API uses OAuth:

Http::globalRequestMiddleware(function ($request) {
    if (str_contains($request->url(), 'api.vendor.com')) {
        // Intercept their API key, swap for OAuth token
        $apiKey = $request->header('X-Vendor-API-Key');
        $oauthToken = $this->exchangeKeyForToken($apiKey);
        
        $request->withoutHeader('X-Vendor-API-Key');
        $request->withHeader('Authorization', "Bearer {$oauthToken}");
    }
    
    return $request;
});

Zero code changes to the vendor package. Zero maintenance burden.

Daryle De Silva

VP of Technology

11+ years building and scaling web applications. Writing about what I learn in the trenches.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *