-
Notifications
You must be signed in to change notification settings - Fork 191
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
[HTTP] Allowing external Http clients #316
Comments
@Guikingone this is a great idea! We will look into it. When this library was built, PSR-7 did not exist yet. We can definitely open this up now though! |
@bshaffer Great news 🎉 Let me know if I can help, thanks again for the feedback and have a great day 🙂 |
@bshaffer would you be open to a PR that makes this repo compliant with PSR-18 known also as http-client? I would try to fully replace the current Guzzle implementation with PSR interfaces, which would obviously break most of the integrations since Guzzle would no longer be provided by this package (new major release would be required). To make the transition easier I can bring http-discovery that would look for any available Http implementations and that would try to use them in case when HTTP client is not provided. Finally, when auto-discover fails I would throw an exception that would recommend the user to install one of available HTTP Client implementations. Since PSR Http Message and PSR Cache are already in place, I think moving to Http Client PSR makes perfect sense. |
@norberttech we are not really interested in this change. If it could be done in a non-breaking way then maybe, but we don't want our auth libraries / clients to throw exceptions requiring users to chose their HTTP client. Potentially, we could require Guzzle, and if the user really didn't want to use it, I believe that's possible with composer's "replace" keyword |
Ok, let me elaborate on this one. 1) Replace Guzzle with HttpClient PSR interfaceLet's first tackle replacing Guzzle with a more generic HttpClient interface. Since Guzzle is implementing In general HttpClient interface gives SDK users full freedom and flexibility on what HTTP client they are willing to use so I hope we all agree this is a good change. So going back to your question:
I believe this can be implemented in a way that would still allow this lib to automatically instantiate the guzzle http client and use it. 2) Remove guzzle dependencyNow a harder one, but let's start from the beginning and let me explain my motivations behind that approach. In general, I consider dependencies as something that I should be always extremely careful and humble about. I do not see myself in a position to decide for other developers what kind of libraries they should use, especially when I can give that decision to the users. But this is my logic and motivation and I understand that other people might prefer different approaches. Ok, Let's look at both approaches (with and without guzzle) from more technical point of view then: a) Guzzle as a dependencyLet's look at the dependencies: guzzlehttp/guzzle:
|
Leaving it up to consumers to pick their preferred implementations is absolutely the way to go IMO. It's rare for a project not to already have an http client hanging around, either by default or by choice - same for factory and message implementations. It's also important to the ecosystem to promote usage of the PSRs for greater interoperability and fewer dependency conflicts |
I don't think this would require a huge amount of work - you can already provide your own "http client" implementation. It's not well documented, and it uses use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
class Psr18HttpHandler
{
public function __construct(private ClientInterface $client)
{
}
/**
* Accepts a PSR-7 request and an array of options and returns a PSR-7 response.
*
* @param RequestInterface $request
* @param array<mixed> $options
* @return ResponseInterface
*/
public function __invoke(RequestInterface $request, array $options = []): ResponseInterface
{
// as "$options" aren't supported in PSR-18, either set them in the $request or $client,
// or don't support them.
return $this->client->sendRequest($request);
}
public function async(RequestInterface $request, array $options = [])
{
// I'm not sure how "async" works in PSR-18...
// This may need to be a hack that just returns a promise wrapped around "sendRequest".
// As this method is NOT used in the auth library, you do not even need to implement it if you're
// passing the credentials in directly
}
} This can be provided when fetching a token: $credentials = ApplicationDefaultCredentials::getCredentials($scope);
$httpClient = new Psr18HttpHandler($client);
$token = $credentials->fetchAuthToken($httpClient); ... or when you create the client library (this will use your handler for auth requests only): use Google\Cloud\Compute\V1\Client\InstancesClient;
$instanceClient = new InstancesClient([
'credentialsConfig' => ['authHttpHandler' => $httpClient]
]); You can also use a custom http handler for each RPC call by configuring the rest transport (but this will require that the $instanceClient = new InstancesClient([
'transport' => 'rest',
'transportConfig' => ['rest' => ['httpClient' => $httpClient]],
]); |
Even if that would be better documented I don't think it's a reasonable approach, duck typing is nice but it's not the most reliable way of defining extension points (http client interface is an extension point from an sdk point of view). Honestly, I would try to discurage people from taking that approach. But again, I'm not trying to force anyone to do anything, if my proposition is not something that you guys are interested in because current solution is just good enough and proposed changes in your eyes are not worth that effort (or for any other reason), that's perfectly fine with me. |
We could add a |
Thanks for stopping by to let us know something could be better!
PLEASE READ: If you have a support contract with Google, please create an issue in the support console instead of filing on GitHub. This will ensure a timely response.
Is your feature request related to a problem? Please describe.
Not related to an issue.
Hi everyone 👋
I'm trying to tweak this library for specific usages and I'm facing an issue when using symfony/http-client, for now, this library use Guzzle as the main HTTP client.
That's a good solution but could it be possible to not depends hardly on it and rather just use the interfaces provided by PSR-18?
The idea here is to allow every HTTP client that follow the interfaces to be used in this library (for example, MeiliSearch does it: https://github.com/meilisearch/meilisearch-php), this way, as developers, we can easily wrap something around it without using Guzzle 🤔
Thanks again for the feedback and have a great day 🙂
Describe the solution you'd like
Describe alternatives you've considered
Additional context
The text was updated successfully, but these errors were encountered: