csarrazi / CsaGuzzleBundle

A bundle integrating Guzzle >=4.0 in Symfony
250 stars 76 forks source link

Provide a way to monitor clients created in code #251

Open nreynis opened 5 years ago

nreynis commented 5 years ago

The bundle only works with guzzle clients which are tagged.

This makes integration difficult or impossible when you have a service that wraps private guzzle clients created "in code". It's not always easy to move the guzzle client to the service layer because their initialization options cannot be changed afterwards by the service using it, which means initialization options must also be exposed in the service layer and cannot be kept encapsulated in the wrapping service. You may also have even more complex use-cases with middlewares using sub clients (ex: guzzle-jwt-middleware).

Would it be possible to provide some kind of factory or configuration builder that would help "instrument" client created in code ? I've scanned through the code and it seems that adding the middlewares to the client stack would be the only thing required. Is that correct ?

Ideally something like this would be great:

class myCustomService {
    private $client;

    public function __construct($arg, $arg2, $arg3, MiddlewareInjector $injector){
        // custom logic
        $stack = HandlerStack::create();
        $injector->instrument($stack);
        $stack->push($myMiddleware);

        $this->client = new Client([
            'headers' => [
                'User-Agent' => 'custom'.$arg1,
                'Content-type' => 'application/json; charset=utf-8'
            ],
            'handler' => $stack,
            'base_uri' => $arg2['endpoint']
        ]);
    }
    public function customAction()
    {
        // use internal client
        $response = $this->client->get("/action");
        // custom logic
    }
}
csarrazi commented 5 years ago

You can actually already do that. The middleware are exposed as services, which can actually be injected in other services. So you could actually get the references to the various middleware you want to use, and that should be it.

To do that, you would only need to inject the stopwatch, history and logger middleware (csa_guzzle.middleware.stopwatch, csa_guzzle.middleware.history, csa_guzzle.middleware.logger). Of course, you would need to take care of the priorities of the different middleware in order to load them in the right order :)