Skip to content

[FrameworkBundle] Fix config for array of base_uri in http_client #53131

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

Open
wants to merge 6 commits into
base: 6.4
Choose a base branch
from

Conversation

Tiriel
Copy link
Contributor

@Tiriel Tiriel commented Dec 18, 2023

Q A
Branch? 6.4
Bug fix? yes
New feature? yes
Deprecations? no
Issues no
License MIT

Allow array of base_uri in config for HttpClient keys, as per comment in PR.

@Tiriel
Copy link
Contributor Author

Tiriel commented Dec 18, 2023

Not sure about the xml conf, advices welcome!

@nicolas-grekas nicolas-grekas modified the milestones: 7.1, 6.3 Dec 19, 2023
@nicolas-grekas nicolas-grekas changed the base branch from 7.1 to 6.3 December 19, 2023 08:03
@nicolas-grekas nicolas-grekas changed the base branch from 6.3 to 7.1 December 19, 2023 08:04
@nicolas-grekas
Copy link
Member

Can you please rebase on 6.3 since this is a bugfix?

@Tiriel Tiriel force-pushed the fix/http-client-configuration branch from a6968d9 to 83ce0a9 Compare December 19, 2023 08:38
@Tiriel Tiriel changed the base branch from 7.1 to 6.3 December 19, 2023 08:39
@Tiriel
Copy link
Contributor Author

Tiriel commented Dec 19, 2023

Rebased on 6.3!

@@ -1901,13 +1901,17 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e
->ifTrue(function ($v) { return !empty($v['query']) && !isset($v['base_uri']); })
->thenInvalid('"query" applies to "base_uri" but no base URI is defined.')
->end()
->validate()
->ifTrue(fn ($v) => (isset($v['base_uri']) && \is_array($v['base_uri'])) && !isset($v['retry_failed']))
->thenInvalid('"base_uri" can only be an array if "retry_failed" is defined.')
Copy link
Member

Choose a reason for hiding this comment

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

defined or enabled for retry_failed?
also, should we validate the array contains only strings?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'd say that more precautions are always better, so indeed checking if there are strings only!
And yeah, retries should be enabled, imo.

Going to make changes in that direction.

Copy link
Member

Choose a reason for hiding this comment

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

In this code we're merging all validations but the error message is the same for all. If you define an array and one of the values is no a string by mistake, you'll see this and will be confusing:

"base_uri" can only be an array if "retry_failed" is defined

Maybe we could extract this validation and create a dedicated error message for it?

\count($v['base_uri']) !== \count(array_filter($v['base_uri'], 'is_string'))

Thanks!

@OskarStark OskarStark changed the title [FrameworkBundle] Fix config for array of base_uri in http_client [FrameworkBundle] Fix config for array of base_uri in http_client Dec 19, 2023
@Tiriel
Copy link
Contributor Author

Tiriel commented Dec 19, 2023

Edit: Edit: Still got a problem with the way base uris are defined.
Configuration-wise the proposed changes seem to work. But not in the field.

On a fresh install in 6.3:

# config/packages/framework.yaml
    http_client:
        scoped_clients:
            test_client:
                base_uri:
                    - 'https://jsonplaceholder.typicode.com/'
                    - 'https://jsonplaceholder.typicode.com/'
                retry_failed:
                    max_retries: 3
// in any controller
    #[Route('/', name: 'app_client')]
    public function index(HttpClientInterface $testClient): Response
    {
        dump($testClient->request('GET', '/posts/1')->toArray());
        // ...
    }

Results in a TypeError: Symfony\Component\HttpClient\ScopingHttpClient::forBaseUri(): Argument #2 ($baseUri) must be of type string, array given since the base_uri are passed when creating the ScopingHttpClient and not the RetryableHttpClient.

Any thought on how to do this? Conditional definition for both seems the most straightforward way, but I'm not sure about that

@Tiriel
Copy link
Contributor Author

Tiriel commented Dec 19, 2023

Made an attempt just as a discussion base. Works as is, but maybe there's a better way to do it or some constraints I haven't tought about.

@Tiriel Tiriel requested a review from nicolas-grekas January 8, 2024 12:46
@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 Feb 1, 2024
@Tiriel
Copy link
Contributor Author

Tiriel commented Apr 23, 2024

Hey there!

Sorry for the ping, I know it's been a while, but could I interest you back in a review around here? @nicolas-grekas maybe, or someone else? This was asked in an issue so maybe we should look into it.

@OskarStark
Copy link
Contributor

OskarStark commented Apr 24, 2024

In the meantime it needs to be rebased on 6.4 please

Allow array of `base_uri` in config for HttpClient keys, as per
[comment in PR](symfony#49809 (comment)).
@Tiriel Tiriel force-pushed the fix/http-client-configuration branch from e76e3ef to 19a43c9 Compare April 25, 2024 14:59
@Tiriel
Copy link
Contributor Author

Tiriel commented Apr 25, 2024

Okay there have been obviously a huge mistake on my part here... Fixing asap.

@Tiriel Tiriel changed the base branch from 6.3 to 6.4 April 25, 2024 15:00
@Tiriel
Copy link
Contributor Author

Tiriel commented Apr 25, 2024

Seems okay with the right destination branch. Sorry for the spam!

@Tiriel
Copy link
Contributor Author

Tiriel commented Apr 29, 2024

Test failures seem unrelated here, but any advice would be welcome!

@Tiriel
Copy link
Contributor Author

Tiriel commented May 31, 2024

Hey there!

Bumping this, as it's still a missing feature. Should I create a new PR to get back in the recent ones?

@lyrixx lyrixx removed their request for review August 13, 2024 08:09
@nicolas-grekas
Copy link
Member

Hi @Tiriel, thanks for your patience.
I think I changed my mind on the topic: this looks like a new feature to me.
To built on this idea, I'm wondering if it wouldn't make more sense to allow a new base_uris option under retry_failed.
That would make everything simpler I think.

@@ -39,12 +39,13 @@ class RetryableHttpClient implements HttpClientInterface, ResetInterface
/**
* @param int $maxRetries The maximum number of times to retry
*/
public function __construct(HttpClientInterface $client, ?RetryStrategyInterface $strategy = null, int $maxRetries = 3, ?LoggerInterface $logger = null)
public function __construct(HttpClientInterface $client, ?RetryStrategyInterface $strategy = null, int $maxRetries = 3, ?LoggerInterface $logger = null, array $baseUris = [])
Copy link
Member

Choose a reason for hiding this comment

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

this change is not needed nor used

@nicolas-grekas nicolas-grekas modified the milestones: 6.4, 7.2 Aug 21, 2024
@Tiriel
Copy link
Contributor Author

Tiriel commented Aug 22, 2024

Hi @Tiriel, thanks for your patience. I think I changed my mind on the topic: this looks like a new feature to me.

That's no problem to me, I'll go and change the PR description!

To built on this idea, I'm wondering if it wouldn't make more sense to allow a new base_uris option under retry_failed. That would make everything simpler I think.

Not sure about that though. I don't know if it's a better idea or not, but I'm not sure about what we should priorize:

  • consistency (keep the base_uri option where it is already defined for the scoped clients)
  • intent behind the change (allow to try multiple uris in case of retry)

Both seem to have pros and cons to me, but ultimately I'll get behind the majority advice (or your, if there not much debate ;) )

@Tiriel
Copy link
Contributor Author

Tiriel commented Aug 22, 2024

Also going to rebase and target the latest branch asap

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Aug 22, 2024

I think base_uris under retry_strategy is more flexible as it allows using scope on top to control how scoped clients behave

@Tiriel
Copy link
Contributor Author

Tiriel commented Aug 22, 2024

Then how do we deal with the base_uri option under each scoped client? Unless I miss something, it would be possible to define a base_uri in a scope client and an array of base_uris in the retry_strategy.

I see four possibilities:

  • adding a base_uri under the scoped client and an array of base_uris in the retry strategy is blocked, raising an exception
  • adding a base_uri under the scoped client and an array of base_uris in the retry strategy is not blocked, base uri from scoped client is kept
  • adding a base_uri under the scoped client and an array of base_uris in the retry strategy is not blocked, base uris from retry strategy are kept
  • adding a base_uri under the scoped client and an array of base_uris in the retry strategy is not blocked, base uri from scoped client is merged inside the array

Personnally, I think the first option (blocking) or the last (merging) are the best, with a preference for the blocking.

@nicolas-grekas
Copy link
Member

I would merge them: the base_uri is prepended to base_uris if any.

@nicolas-grekas
Copy link
Member

nicolas-grekas commented Aug 22, 2024

Hum, actually no: we'd need to make setting both base_uri and base_uris conflict, and we'd then need to compute a regular expression that "|" all base_uris so that scoped clients accepts them all in its scope (unless scope is set).

@nicolas-grekas
Copy link
Member

Alternatively, if we keep base_uri as allowing an array, we could make defining a retry_strategy optional (and auto-enable it then).
We also need to allow setting both a scope and an array of base_uris for completeness (both options are exclusive at the moment).

WDYT?

@Tiriel
Copy link
Contributor Author

Tiriel commented Aug 26, 2024

Alternatively, if we keep base_uri as allowing an array, we could make defining a retry_strategy optional (and auto-enable it then).

This seems like a better option to me, a bit more friendly to use

We also need to allow setting both a scope and an array of base_uris for completeness (both options are exclusive at the moment).

This seems a bit redundant. IIRC, scope makes the configuration active only on uris matching the scope. So if you set an array of base uris and the scope, the scope will simply be active on every call since the base uris matching the scope will be prepended to each call.

In this case, I haven't looked at feasability yet, but maybe we could have a unified scope/base_uri option, working differently depending on the actual call you make: when calling request, if you pass a full uri with scheme/host, it works as scope, and if you pass a path, it prepends the base uri.

Seems a lot of work though, and not necessarily on the scope of this PR.

@fabpot fabpot modified the milestones: 7.2, 7.3 Nov 20, 2024
@fabpot fabpot modified the milestones: 7.3, 7.4 May 26, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants