Skip to content
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

Migrate Guzzle to Symfony Http Client #45

Merged

Conversation

boherm
Copy link
Member

@boherm boherm commented Nov 6, 2023

Questions Answers
Description? Migrate Guzzle to Symfony Http Client.
We can use Guzzle Client if we really want, to knew more about this, you can read the README.md file.

Tests are updated too (for php versions: 7.2, 7.3, 7.4, 8.0, 8.1, 8.2):
- Coding standard
- Commons tests for the library
-Guzzle Client implementation tests
- Symfony Http Client (all versions: ^5.4|^6) implementation tests
Type? refactor
BC breaks? yes
Deprecations? no
Fixed ticket? Fixes PrestaShop/PrestaShop#32855
Sponsor company PrestaShop SA
How to test? You can read the Readme to tests this new implementation and also the Guzzle implementation too.

@boherm
Copy link
Member Author

boherm commented Nov 6, 2023

edit: PR merged! So this one are open to reviews!

CI is failing because of cs-fixer.
Before merge this PR, we need #46.

@boherm boherm marked this pull request as draft November 6, 2023 11:14
@boherm boherm marked this pull request as ready for review November 6, 2023 14:12
Copy link
Contributor

@matks matks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that puzzles me

src/Client/SymfonyHttpClient.php Outdated Show resolved Hide resolved
Copy link
Contributor

@matks matks left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, how do we test?

@@ -14,7 +14,8 @@
}
],
"require": {
"guzzlehttp/guzzle": "^7.3"
"php": ">=7.2.5",
"symfony/http-client": "^5.4"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will the transition to v 6 require modifications? I ask this because we are soon going to switch to symfony 6 in the core

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In fact, if we move to Symfony Http Client v6, we need to drop PHP 7.2 version for circuit-breaker too.
I think that could be done in another PR in the future.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I didn't think I would do it on the same PR, but it's potentially something to do in the future

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can allow multiple versions? 🤔

Suggested change
"symfony/http-client": "^5.4"
"symfony/http-client": "^5|^6"

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the contract change that much on the http client itself?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jolelievre, not that much, your suggestion can work properly, I will change that today 😉

{
if (isset($options['method'])) {
if (!in_array($options['method'], self::SUPPORTED_METHODS)) {
throw UnsupportedMethodException::unsupportedMethod($options['method']);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a test that checks for the error could be a good thing

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're right, and maybe for the GuzzleClient too, what do you think? 🤔

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, also 👍

@boherm
Copy link
Member Author

boherm commented Nov 7, 2023

@matks Hum, isn't easy to test this.
I think that the best way to test is to follow this steps:

  • Clone my fork and checkout the #32855-symfony-http-client branch.
  • Install composer link (to easily link the library to your cloned version).
  • From your PrestaShop folder: composer link ../path/to/cloned-repository
  • Then look at the circuit-breaker readme to instantiate a new factory and client with some configuration.
  • Make sure that by default the client is SymfonyHttpClient and not Guzzle.
  • Play with url that exist or not and see if the fallback callback work!
  • Try the same with GuzzleClient.

(At the end, don't forget to make a composer unlink ../path/to/cloned-repository.)

Copy link
Contributor

@jolelievre jolelievre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @boherm

Just a few comments, and also you need to modify the GuzzleClient among other things we still have a use statement here

use GuzzleHttp\Client as OriginalGuzzleClient;
on a class that is potentially not present

I had something in mind, although I'm not sure it's the good way to do this, to remove the use statement and instead the GuzzleClient must act as factory and:

  • use the FQCN of the guzzle original client via a hard coded string value \GuzzleHttp\Client
  • use class_exists to check if the class is available, throw an exception if it's not
  • if it exists you can do something like $className = '\GuzzleHttp\Client'; $client = new $className($options)

I think if we want the code to be completely uncoupled from the guzzle dependency it's a good way to remove all dependencies in the code, what do you think?

@@ -14,7 +14,8 @@
}
],
"require": {
"guzzlehttp/guzzle": "^7.3"
"php": ">=7.2.5",
"symfony/http-client": "^5.4"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can allow multiple versions? 🤔

Suggested change
"symfony/http-client": "^5.4"
"symfony/http-client": "^5|^6"

@@ -14,7 +14,8 @@
}
],
"require": {
"guzzlehttp/guzzle": "^7.3"
"php": ">=7.2.5",
"symfony/http-client": "^5.4"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the contract change that much on the http client itself?

// Symfony Http Client not support "method" passed in options array.
unset($options['method']);
// For mock purpose, we can pass a handler in options array in a Guzzle way.
if (isset($options['handler']) && $options['handler'] instanceof MockHttpClient) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This way of mocking the client/handler was a bit nasty But mostly it's really based on an option that's purely and only meaningful for Guzzle we shouldn't handle a similar handler option if it's not handled by the symfony client

There's probably a smarter and cleaner way to handle tests and mock for a symfony client, one that is not inspired from guzzle but more adapted to Symfony client, maybe even a client option that overrides the OriginalSymfonyHttpClient::create would be a bit better

@@ -64,7 +64,7 @@ public function testCircuitBreakerWithDispatcher(): void
->getMock()
;

$localeService = 'file://' . __FILE__;
$localeService = 'https://prestashop-projects.org/';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why changing the local accessible URL to an external one? The tests were independent from a tier service so far, what's the advantage of changing that, if prestashop-projects.org is don the tests ould fail without a valid reason

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After some tests on my side, we can only access to an external url with Symfony Http Client 😅

@@ -108,7 +105,7 @@ public function testSimpleCall(): void
return false;
});
$this->assertSame(State::CLOSED_STATE, $circuitBreaker->getState());
$this->assertEquals(0, $mock->count());
$this->assertEquals(1, $mock->getRequestsCount());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know the mock is not the same anymore so it behaves differently but the modified values seem a bit off compared to the initially tested feature 🤔 Are we sure we're still validating correctly the circuit breaker behaviour..

protected function setUp(): void
{
// Skip tests if GuzzleHttp\Client is not installed
if (!class_exists('GuzzleHttp\Client')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK but then it means that we actually never test the guzzle client right? 🤔
Maybe we should still keep guzzle in the require-dev in composer so that we can still run tests in the CI

@boherm boherm force-pushed the #32855-symfony-http-client branch 7 times, most recently from 2670573 to f6ce2f8 Compare November 10, 2023 09:00
Copy link
Contributor

@matthieu-rolland matthieu-rolland left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's qa-dev aproved 👍

  • I applied your PR on circuit-breaker in a prestashop, called an url after making sure I was using your PR, and it works.
  • The timeout also still works as usual => the fallback answer is given when timeout is exceeded
  • ps_distributionapiclient is still working correctly as well with your PR on circuit-breaker

@matthieu-rolland matthieu-rolland merged commit 1ff44e3 into PrestaShop:develop Nov 20, 2023
26 checks passed
@boherm boherm deleted the #32855-symfony-http-client branch November 20, 2023 09:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Archived in project
5 participants