Skip to content

[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

Merged
merged 1 commit into from
Apr 20, 2021

Conversation

nicolas-grekas
Copy link
Member

@nicolas-grekas nicolas-grekas commented May 30, 2020

fabpot added a commit to symfony/symfony that referenced this pull request Jun 9, 2020
…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
@symfony symfony deleted a comment from fabpot Jun 9, 2020
@wouterj wouterj added this to the 5.2 milestone Oct 17, 2020
@xabbuh xabbuh changed the base branch from master to 5.2 November 17, 2020 10:07
@AndreasA
Copy link

AndreasA commented Dec 2, 2020

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'

@nicolas-grekas
Copy link
Member Author

Maybe this one could be merged?

@javiereguiluz
Copy link
Member

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!

@nicolas-grekas nicolas-grekas deleted the hc-asyncdecorator branch April 20, 2021 13:50
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.

9 participants