Hey Woody,

I was speaking with Matthieu Napoli and Joel Wurtz (HTTPlug contributor) 
about PSR-15 last week at Paris ForumPHP. If I correcly remember the 
discussion we had, the general consensus was that PSR-15 should indeed 
focus on the server side middlewares.
Client middlewares are a different kind of beast. I don't think you will 
face a big pushback if you decide to focus PSR-15 on server side 
middleware. This is what people expect from PSR-15.

Furthermore, HTTPlug is already trying to standardize client side 
middlewares (see 
http://docs.php-http.org/en/latest/plugins/introduction.html) and they may 
want to push a PSR based on their work in the future.

++
David.


Le lundi 31 octobre 2016 14:50:39 UTC+1, Woody Gilk a écrit :
>
> Michael,
>
> Thanks for bringing this up. For historical context, I have always thought 
> of "client middleware" as middleware that does not require the additional 
> methods defined in ServerRequestInterface. The consideration of async vs 
> sync requests was never something that entered my mind.
>
> Reviewing the Guzzle docs again (as the most mature PSR-7 client-focused 
> package I know of) it certainly appears that the current PSR-15 signatures 
> would not work there. That is obviously a serious flaw.
>
> However, since there is not currently a ratified PSR for async, perhaps 
> the best thing to do would be to repurpose PSR-15 to be entirely 
> server-focused middleware? I would rather defer the creation of a spec for 
> client middleware until the async PSR is complete.
>
> Would that be an acceptable situation for you? I don't want to create 
> something that async clients will never be able to use.
>
> Regards,
>
> --
> Woody Gilk
> http://about.me/shadowhand
>
> On Sat, Oct 29, 2016 at 4:47 PM, Michael Mayer <mic...@schnittstabil.de 
> <javascript:>> wrote:
>
>> Hi everyone,
>>
>> I'm a little bit surprised to see so many suggestions about how 
>> ServerMiddlewareInterface and ClientMiddlewareInterface should look like, 
>> obviously without much knowledge about the client-side.
>>
>> The current state 
>> <https://github.com/php-fig/fig-standards/blob/82e2d1c1fd9a3782e0707cf0d4449b28cca8ffa9/proposed/http-middleware/middleware.md>
>>  
>> is:
>>
>> interface MiddlewareInterface {}
>>
>> interface ClientMiddlewareInterface extends MiddlewareInterface
>> {
>>     public function process(RequestInterface $request, DelegateInterface 
>> $next);
>> }
>>
>> interface ServerMiddlewareInterface extends MiddlewareInterface
>> {
>>     public function process(ServerRequestInterface $request, 
>> DelegateInterface $frame);
>> }
>>
>> interface DelegateInterface
>> {
>>     public function next(RequestInterface $request);
>> }
>>
>>
>> <https://github.com/php-fig/fig-standards/blob/master/proposed/http-middleware/middleware.md#23-psrhttpmiddlewareclientmiddlewareinterface>
>>
>>
>>
>> Here are some falsehoods about the client-side, the list seems, by far, 
>> not exhaustive.
>>
>> *1. HTTP Clients return their results synchronously*
>> It would be very clumsy to load a web page nowadays with all its assets 
>> sequentially. Thus HTTP clients like Guzzle 
>> <https://github.com/guzzle/guzzle> use asynchronous techniques like 
>> Promises (e.g. Guzzle Promises <https://github.com/guzzle/promises>), 
>> callbacks (e.g. node.js), generator based control flow, etc.
>>
>> An example:
>>
>> $request = new \GuzzleHttp\Psr7\Request('GET', 'http://httpbin.org');
>> $promise = $client->sendAsync($request)->then(function ($response) {
>>     echo 'I completed! ' . $response->getBody();
>> });
>>
>>
>> *2. Client Middlewares just transform Requests to Responses, doing it 
>> **synchronously 
>> is not a problem*
>> Maybe, this is appropriate on the server side, but not on the client. 
>> Just think about a Middleware which adds cookies to requests.
>>
>> From GuzzleHttp/Middleware 
>> <https://github.com/guzzle/guzzle/blob/5a5893c19f798175869eb94a88bb0b73e7acfb05/src/Middleware.php#L17-L44>
>> :
>> return function ($request, array $options) use ($handler) {
>>     // …
>>     $request = $cookieJar->withCookieHeader($request);
>>     return $handler($request, $options)
>>         ->then(function ($response) use ($cookieJar, $request) {
>>             $cookieJar->extractCookies($request, $response);
>>             return $response;
>>         }
>>     );
>> };
>>
>> The Middleware have to:
>>
>>    1. add the current cookie to the header: ->withCookieHeader($request)
>>    2. call the delegate: $handler($request, $options)
>>    3. extract the cookie
>>
>> As the delegate returns a promise, we need to: $handler(…)->then(…).
>> Can we do better, e.g. use a sync delegate/handler? Nope, this would lead 
>> to call $promise->wait() within the delegate, which isn't performant. 
>>
>> *3. Client Middlewares call their delegate almost once*
>> For the client-side it's absolutely valid to retry a request, e.g. 
>> GuzzleHttp/RetryMiddleware 
>> <https://github.com/guzzle/guzzle/blob/113071af3b2b9eb96b05dab05472cbaed64a3df4/src/RetryMiddleware.php>
>>
>> *4. Client Middlewares don't need to create requests, they can modify the 
>> given $request*
>> Just think about an authorization middleware, e.g. for OAuth or similar.
>> It would be dangerous or at least very odd to reuse $request for login 
>> endpoints:
>> class AuthMiddleware implements ClientMiddlewareInterface
>> {
>>     // …
>>     public function process(RequestInterface $request, DelegateInterface 
>> $next)
>>     {
>>         if ($this->accessToken === null) {
>>             $loginRequest = $this->createLoginRequest();
>>             $this->accessToken = $next->next($loginRequest)->getBody()->
>> getContents();
>>         }
>>
>>         $request = $request->withHeader('Authorization', $this->
>> accessToken);
>>         return $next($request);
>>     }
>>
>>
>>     private function createLoginRequest()
>>     {
>>         $req = $this->requestFactory->createRequest('POST', '/login');
>>         // add $login, $password…
>>         return $req;
>>     }
>> }
>>
>> This was just some food for thought, hopefully pushing PSR-15 a bit 
>> forward.
>>
>> Best regards,
>> Michael
>>
>> -- 
>> You received this message because you are subscribed to the Google Groups 
>> "PHP Framework Interoperability Group" group.
>> To unsubscribe from this group and stop receiving emails from it, send an 
>> email to php-fig+u...@googlegroups.com <javascript:>.
>> To post to this group, send email to php...@googlegroups.com 
>> <javascript:>.
>> To view this discussion on the web visit 
>> https://groups.google.com/d/msgid/php-fig/f57bb59a-5784-4e6d-aaea-bd738e49a00b%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/php-fig/f57bb59a-5784-4e6d-aaea-bd738e49a00b%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
You received this message because you are subscribed to the Google Groups "PHP 
Framework Interoperability Group" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to php-fig+unsubscr...@googlegroups.com.
To post to this group, send email to php-fig@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/php-fig/82ea4a8e-30db-4cee-98ae-5c1f014c4cd6%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to