-
-
Notifications
You must be signed in to change notification settings - Fork 433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow replacing the guzzle handler #956
Conversation
This allows setting e.g. Amp\Http\Client\GuzzleAdapter\GuzzleHandlerAdapter, allowing the whole firebase-php environment to transparently run asynchronously. Up to now this required very ugly hacking manipulating private fields directly, like: (fn() => (fn() => (fn() => (fn() => $this->handler = new GuzzleHandlerAdapter)->call($this->config["handler"]))->call($this->client))->call($this->messagingApi))->call($messaging); Which is not exactly ergonomic.
Ugh, yes, this is indeed ugly 😅, thank you for bringing this up, we definitely need to change this. The I'm hesitant to add another method/property to the class because I'm planning to deprecate all methods in favor of the already existing So, instead of using $options = HttpClientOptions::default()
->withTimeOut(3.5)
->withProxy('tcp://<host>:<port>'); one would use use GuzzleHttp\RequestOptions;
$options = HttpClientOptions::default()
->withGuzzleClientOptions([
RequestOptions::TIMEOUT => 3.5,
RequestOptions::PROXY => 'tcp://<host>:<port>',
]); This would make it easier to provide any config for the Guzzle Client, and not those that are exposed through the This would then make it easy to add a key for then use GuzzleHttp\RequestOptions;
$options = HttpClientOptions::default()
->withGuzzleClientOptions([
RequestOptions::TIMEOUT => 3.5,
RequestOptions::PROXY => 'tcp://<host>:<port>',
])
->withGuzzleClientOption('handler', ...) // or directly in the array above
; With this already being possible, the only remaining change would be a a check in the factory like $handler = HandlerStack::create($config['handler'] ?? null); What do you think? |
The problem with that is the obviousness of discoverability. Like, how do I know there's an arbitrary additional option named "handler" without actually looking into the source code? I mean, what you propose definitely solves the problem, but I have some doubts on the superiority of that approach. |
I get it! Let's keep it the way it is then for the moment, and I'll think about it more when time comes - but I would hate having to add methods for every single! To be fair - if someone is looking to replace the default handler with a custom one, they probably know Guzzle well enough 😅) Going into the PR - I still wouldn't add a new # HttpClientOptions
/**
* @param callable(RequestInterface, array): PromiseInterface $value
*/
public function withGuzzleHandler(callable $handler): self
{
return $this->withGuzzleConfigOption('handler', $value);
} and # Factoy
/**
* @param array<non-empty-string, mixed>|null $config
* @param array<callable(callable): callable>|null $middlewares
*/
public function createApiClient(?array $config = null, ?array $middlewares = null): Client
{
// ...
$handler = HandlerStack::create($config['handler'] ?? null);
// ...
} Meaning: giving users the benefit of discoverability through auto-completion but using only the "source of truth" being the Guzzle Config array |
To be honest, I have barely any idea of guzzle, but I just know that there's an adapter I can just use to make any usage of guzzle async and have my code just work :-) Assuming adding something to the guzzle config is fine, as long as having some custom unused values in there isn't harming guzzle? |
Merged with db50265 - thanks again! |
This allows setting e.g.
Amp\Http\Client\GuzzleAdapter\GuzzleHandlerAdapter
, allowing the whole firebase-php environment to transparently run asynchronously.Up to now this required very ugly hacking manipulating private fields directly, like:
Which is not exactly ergonomic.