Skip to content

Conversation

saeedhosan
Copy link

@saeedhosan saeedhosan commented Sep 28, 2025

✨ Feature: Guzzle Middleware for Laravel HTTP Events

Summary

Added a GuzzleHttp middleware that dispatches Laravel HTTP client events for better integration.

Benefits

Changes

  • Implemented custom Guzzle middleware using class GuzzleHttpAdapter
  • Ensured Laravel Http:: event listeners are triggered properly
  • Added Pest tests to validate request, response, and middleware behavior

Updated Core ServiceProvider

This update required modifying the package's core service provider implementation.

Currently

->withHttpClient(GuzzleHttpAdapter::timeout(config('openai.request_timeout')));

Previously

->withHttpClient(new \GuzzleHttp\Client(['timeout' => config('openai.request_timeout', 30)]));

✅ Tests

All Pest tests passed successfully.


Type: feat(http)

@iBotPeaches
Copy link
Collaborator

Did you have any inspiration from some battle-tested packages? I'm a bit concerned of swapping out the default HTTP client for some homegrown implementation. Maybe we can have a specific flag that invokes this for a bit of A/B testing.

Or if not - any links I can read on how emitted these events creates something Laravel can react with.

@saeedhosan
Copy link
Author

saeedhosan commented Oct 6, 2025

Thanks for the feedback!

Did you have any inspiration from some battle-tested packages?

Not directly — the idea came from our org project, where we needed every request/response logged consistently.

About swapping the default HTTP client — I understand the concern. Instead of replacing it, we can keep using Guzzle and let users use pre-defined or custom handlers: Guzzle HandlerStack.
For example, we can pre-define handlers to automatically dispatch Laravel HTTP events, which helps with Telescope, logging, etc.

Alternatively, this option will allows users to create and use their own custom HTTP handler to interact request/response using handler HandlerStack.

Example config:
The config will accept callable | null | string-class

// config/openai.php
'http_handler' => \App\Http\Handlers\CustomHandler::class,

Example Package-defined handlers:

// config/openai.php
'http_handler' => \OpenAI\Http\Handlers\DefaultHandler::class,

Example ServiceProvider setup:

...
->withHttpClient(new \GuzzleHttp\Client([
    'timeout' => config('openai.request_timeout', 30),
    'handler' => TheResolverClass::resolve(config('openai.http_handler')),
]));

Example User Handler class would look:

namespace App\Http\Handlers;

class CustomHandler
{
    /**
     * The handler execute.
     */
    public function __invoke(): void
    {
        // logic here
    }
}

This keeps the package used client compatibility while giving users flexibility. I can update the PR with this handler-based approach, including tests and docs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants