-
-
Notifications
You must be signed in to change notification settings - Fork 5.2k
[HttpClient] add doc about extending and AsyncDecoratorTrait #13736
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
Conversation
f3bc1b0
to
542a8d5
Compare
…g responses without breaking async (nicolas-grekas) This PR was merged into the 5.2-dev branch. Discussion ---------- [HttpClient] add AsyncDecoratorTrait to ease processing responses without breaking async | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | Deprecations? | no | Tickets | Fix #31885, fix #32367 | License | MIT | Doc PR | symfony/symfony-docs#13736 This PR allows processing the stream of chunks. ```php <?php $client = new class() implements HttpClientInterface { use AsyncDecoratorTrait; public function request(string $method, string $url, array $options): ResponseInterface { return new AsyncResponse($method, $url, $options, static function (ChunkInterface $chunk, AsyncContext $context) { // do what you want with chunks, e.g. split them // in smaller chunks, group them, skip some, etc. yield $chunk; }); } }; ``` Some ideas: - custom retry/redirect logic - align chunk boundaries with server-sent events and yield augmented chunks that know about messages (see #36692) - play some OAuth dance before issuing the real request - do some live transclusion - be creative :) Any custom logic should fit into the `$passthru` filter iterator (the last constructor argument of `AsyncResponse`). There, one has access to an `AsyncContext` DTO, which allows controlling the stream, eg. to replace the current request/response, to change the passthru filter itself, etc. The surrounding logic will catch badly behaving filters to ease spotting some mistakes (eg. never forwarding an "isLast()" chunk, or yielding extra chunks after an "isLast()" one, etc.) For the record: - When the chunk passthru issues many internal requests in order to complete the external one, the info of each internal request is accessible via the `previous_info` entry. I considered merging all internal `response_headers` info under the main one since that's possible, but I'm not sure it's worth the added complexity. Please tell me if you think we should do it. - A future iteration/PR might add support for time-based events. Right now, implementing a pause in the stream involves calling `usleep()`, but this doesn't play really well with async. Implementing small pauses and summing them up to the target pause might be good enough - we'll need to give it a try to know better. Commits ------- 766a1c6 [HttpClient] add AsyncDecoratorTrait to ease processing responses without breaking async
542a8d5
to
cd298a8
Compare
cd298a8
to
c474542
Compare
c474542
to
637014e
Compare
637014e
to
f41ef12
Compare
It would be great to know if this could also be used as authentication middleware, e.g. for OAuth2 and if so, a short example how one could use it. I guess in both cases - using the AsynDecoratorTrait and not using it to provde a middleware I would use the Symfony service decoration, correct? So like: services:
My\MyService:
decorates: 'Symfony\Component\HttpClient\HttpClient' |
Maybe this one could be merged? |
Thanks Nicolas! Sorry it took us so long to merge. I like the new docs because they are easy to read and they provide both examples and references to learn more. Cheers! |
About symfony/symfony#36779 and symfony/symfony#37136