I don't understand the question.

What do you mean by "middleware that does not return a response"?

Middleware always returns a response - the interface return-type stipulates
that.

I've never heard of middleware that does not return?


On Sat, May 13, 2017 at 6:52 PM, Woody Gilk <woody.g...@gmail.com> wrote:

> David,
>
> What I don't underhand about your proposal is how a middleware that does
> not return a response would be implemented. For instance, a middleware that
> sets parsedBody?
>
> I also don't understand how this would solve the DI concern. It looks like
> any middleware that wants to continue processing would need a reference to
> the next middleware factory, as in:
>
> return $this->next->createMiddleware($this)->process($request);
>
> Perhaps you could provide some implementation details to help me
> understand how this would work?
>
> On Sat, May 13, 2017, 07:00 Rasmus Schultz <ras...@mindplay.dk> wrote:
>
>> Very good summary and well argued, thanks David!
>>
>> The factory pattern you're proposing is very similar to what Shelf does
>> in Dart - the only real difference is they're doing it with typedefs, but
>> yes, we can accomplish effectively the same thing with interfaces.
>>
>> In my opinion, this approach will provide considerably better modularity
>> than the current proposal, because it will make it very easy to composer a
>> few middlewares insides a middleware-factory, which in turn will make it
>> very easy to host several of these multi-middlewares ("modules" if you
>> like) as part of an application, whether manually bootstrapped or
>> auto-magically by priority using some kind of framework.
>>
>> I think this will provide more architectural freedom, and will make it
>> much easier to write handlers or middleware that composes multiple handlers
>> - e.g. being able to compose two or more low-level handlers or middleware
>> into a more high-level handler or middleware, without needing to depend on
>> a dispatcher or "pipe" implementation. This helps alleviate dependency
>> issues too - if I ship a middleware internally composed of one or more
>> internal handlers, I don't have to ship that component with a dependency on
>> a specific dispatcher/pipe.
>>
>> The only thing I disagree with is the term "middleware" - the
>> handler-interface need not be designated as middleware-specific, it has
>> many much more versatile uses. For example, a dispatcher or framework can
>> provide both a handler for direct use, as well as factory that makes it
>> easy to compose an instance of a sub-stack as part of your
>> application-stack.
>>
>> So we really do need to standardize on handlers first.
>>
>> https://github.com/http-message-strategies-interop/
>> fig-standards/blob/http-message-strategies/proposed/
>> http-message-strategies/http-message-strategies.md
>>
>>
>> On Sat, May 13, 2017 at 12:38 PM, David Négrier <david.negr...@gmail.com>
>> wrote:
>>
>>> Hey guys,
>>>
>>> Catching up on the thread. Just read Matthew's and Beau's post as well
>>> as Rasmus ones.
>>>
>>> I'm still surprised because I feel like I proposed a solution to the
>>> problem 2 weeks ago and nobody noticed (or cared to point me that I'm
>>> wrong).
>>>
>>> So I'll try to explain it again.
>>>
>>> Rasmus is annoyed by the current proposal because a middleware might
>>> have 0 or many delegates (but the current proposal only allows for one
>>> "main" delegate.
>>> Yet, if we remove the delegate and go the "Stack" way, working with DI
>>> containers becomes a real mess. In particular, it becomes almost impossible
>>> to write "bundles" that ship middlewares that should be applied by a
>>> priority index. Or we need to rely on a "convention" (like next middleware
>>> being passed as first argument of the constructor), and we know conventions
>>> suck.
>>>
>>> But we can really solve this:
>>>
>>> interface ServerMiddlewareInterface // aka the HandlerInterface
>>> {
>>>     public function __invoke(ServerRequestInterface $request) :
>>> ResponseInterface
>>> }
>>>
>>>
>>> interface MiddlewareFactoryInterface
>>> {
>>>     public function createMiddleware(ServerMiddlewareInterface $next) :
>>> ServerMiddlewareInterface
>>> }
>>>
>>> The first interface is the "HandlerInterface" Rasmus is talking about.
>>> It is the "purest" thinkg we can imagine. A class that takes a request and
>>> returns a response.
>>> But as we know, it does not play well with Pipes/Stacks. So rather that
>>> stacking middlewares (or handlers), I'm proposing we are stacking
>>> "Middleware factories". Factories are objects that create a middleware
>>> given the "next" middleware.
>>>
>>> So this:
>>>
>>> ```php
>>> $app->route('/api/blog', [
>>>     Authentication::class,
>>>     Authorization::class,
>>>     Blog::class,
>>> ], ['GET', 'POST']);
>>> ```
>>>
>>> becomes this:
>>>
>>> ```php
>>> $app->route('/api/blog', [
>>>     AuthenticationFactory::class,
>>>     AuthorizationFactory::class,
>>>     BlogFactory::class,
>>> ], ['GET', 'POST']);
>>> ```
>>>
>>> From the list of factories, we can create back the middlewares.
>>>
>>> Look at the signature of the factory:
>>>     public function createMiddleware(ServerMiddlewareInterface $next) :
>>> ServerMiddlewareInterface
>>>
>>> The factory will be passed the "next" middleware/handler (or a
>>> delegate/proxy, this is an implementation detail) and return the created
>>> middleware.
>>>
>>> Doing things this way has a ton of advantages:
>>>
>>> - it answers Rasmus concerns:
>>>     - we are standardizing the "HandlerInterface" (or
>>> MiddlewareInterface, whatever the name)
>>>     - Middlewares can have 0, 1 or many delegates, it does not matter
>>> regarding this interface
>>>     - you can use only "Handlers/Middlewares" directly in your
>>> application and disregard middleware factories completely if you don't use
>>> them
>>> - yet, it answers Matthew's concerns too:
>>>     - it plays well with DI, as you can stack/pipe middleware factories
>>>     - it does not rely on a convention
>>>     - depending on the way you implement your framework, you can have
>>> lazy instantiation of the middlewares (for instance using proxies)
>>>
>>> Even better, regarding performance, it can be quite quick too. Just
>>> imagine a scenario where you use ReactPHP (and therefore, middlewares are
>>> reused). Using middleware factories, the middleware "tree" is constructed
>>> once at the beginning of the application and then, the request is piped
>>> from one middleware to the next one without going through the "delegate" we
>>> currently have (so it should be faster in the case of ReactPHP).
>>>
>>> This proposal looks a lot like Stack, but it removes the convention part
>>> and replaces it with a factory interface.
>>>
>>> I'd be interested in having Beau and Matthew feedback on this idea. Do
>>> you see the benefit? Is something not clear? Or is there a flaw I did not
>>> see?
>>>
>>> ++
>>> David.
>>>
>>>
>>>
>>> Le vendredi 12 mai 2017 12:49:36 UTC+2, Rasmus Schultz a écrit :
>>>>
>>>> > I don't think it is at all natural to say "all middleware must be
>>>> context free and middleware order never matters". That's simply 
>>>> unrealistic.
>>>>
>>>> That's not what I'm saying.
>>>>
>>>> Of course middleware components are going to communicate facts about
>>>> the state of the Request and Response - that's the whole point.
>>>>
>>>> Of course middleware order matters, as far as getting a meaningful
>>>> result, I'm not trying to say otherwise.
>>>>
>>>> What I'm saying is, if you use the Request object as a transport
>>>> mechanism for your _domain_ objects, stuffed into reserved attributes,
>>>> you're first of all using the Request object as a service locator, which is
>>>> bad practice.
>>>>
>>>> You're no longer communicating facts about the state of the Request or
>>>> Response, you're just overloading the Request model as a means to avoid
>>>> dealing with a dependency issue. Worse, you're hiding the fact that
>>>> dependency exists, as is the general issue with service location.
>>>>
>>>> There are always going to be better, cleaner, simpler, more transparent
>>>> patterns that don't hide your dependencies or solve the problem by using
>>>> the Request model as a kind of "container" for your domain objects.
>>>>
>>>> IN MY OPINION, attributes in the Request object are widely abused as a
>>>> general solution to all sorts of dependency issues, when, really, they
>>>> probably ought not to be used for much else other than an additional source
>>>> of parameters.
>>>>
>>>> Per the PSR-7 definition, attributes hold "parameters derived from the
>>>> request" - I find that stuffing your domain objects in there under reserved
>>>> keys is a bit of a stretch, even if your domain objects were somehow
>>>> "derived from the request", with examples given such as "the results of
>>>> path match operations; the results of decrypting cookies; the results of
>>>> deserializing non-form-encoded message bodies; etc.", I think it's quite a
>>>> long reach.
>>>>
>>>> Bottom line, if it doesn't really function like middleware, why did you
>>>> implement it as middleware? Wrong abstraction for the job.
>>>>
>>>>
>>>> On Wed, May 10, 2017 at 11:36 PM, Woody Gilk <woody...@gmail.com>
>>>> wrote:
>>>>
>>>>> On Wed, May 10, 2017 at 1:54 PM, Rasmus Schultz <ras...@mindplay.dk>
>>>>> wrote:
>>>>>
>>>>>> In my opinion, if a middleware component doesn't work when taken out
>>>>>> of context from other middleware, or is dependent on related middleware 
>>>>>> and
>>>>>> execution order etc., it's no longer middleware, strictly speaking - at
>>>>>> that point, you're overloading the middleware mechanism with
>>>>>> responsibilities that don't belong to that domain and don't naturally fit
>>>>>> there.
>>>>>
>>>>>
>>>>> That's purely an opinion and I definitely don't agree about the
>>>>> execution order. Would this make sense:
>>>>>
>>>>> middleware = [
>>>>>   ActionHandler,
>>>>>   ClientIp,
>>>>>   Authorization,
>>>>> ]
>>>>>
>>>>> Of course not! Some middleware will always need to be early or late in
>>>>> processing. Authentication and authorization will need to be early, and
>>>>> action handling will need to be late. I don't think it is at all natural 
>>>>> to
>>>>> say "all middleware must be context free and middleware order never
>>>>> matters". That's simply unrealistic.
>>>>>
>>>>> --
>>>>> Woody Gilk
>>>>> http://about.me/shadowhand
>>>>>
>>>>> --
>>>>> You received this message because you are subscribed to a topic in the
>>>>> Google Groups "PHP Framework Interoperability Group" group.
>>>>> To unsubscribe from this topic, visit https://groups.google.com/d/
>>>>> topic/php-fig/B3jtdJA7-6w/unsubscribe.
>>>>> To unsubscribe from this group and all its topics, send an email to
>>>>> php-fig+u...@googlegroups.com.
>>>>> To post to this group, send email to php...@googlegroups.com.
>>>>> To view this discussion on the web visit https://groups.google.com/d/
>>>>> msgid/php-fig/CAGOJM6%2BKW4nFeyMb07%3DGvY0C9nj9ChtrCe8cHLAiJJs%
>>>>> 3DPwjd-w%40mail.gmail.com
>>>>> <https://groups.google.com/d/msgid/php-fig/CAGOJM6%2BKW4nFeyMb07%3DGvY0C9nj9ChtrCe8cHLAiJJs%3DPwjd-w%40mail.gmail.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 a topic in the
>>> Google Groups "PHP Framework Interoperability Group" group.
>>> To unsubscribe from this topic, visit https://groups.google.com/d/
>>> topic/php-fig/B3jtdJA7-6w/unsubscribe.
>>>
>> To unsubscribe from this group and all its topics, 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/3d95b640-8571-4937-91e7-30277b7a97cd%40googlegroups.com
>>> <https://groups.google.com/d/msgid/php-fig/3d95b640-8571-4937-91e7-30277b7a97cd%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/CADqTB_gewQz6bfoVKUy1tNQVnHf0u%
>> 3DePezbnW-ubmEaewZQCBQ%40mail.gmail.com
>> <https://groups.google.com/d/msgid/php-fig/CADqTB_gewQz6bfoVKUy1tNQVnHf0u%3DePezbnW-ubmEaewZQCBQ%40mail.gmail.com?utm_medium=email&utm_source=footer>
>> .
>> For more options, visit https://groups.google.com/d/optout.
>>
> --
>
> Woody Gilk
> http://about.me/shadowhand
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "PHP Framework Interoperability Group" group.
> To unsubscribe from this topic, visit https://groups.google.com/d/
> topic/php-fig/B3jtdJA7-6w/unsubscribe.
> To unsubscribe from this group and all its topics, 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/CAGOJM6LqjaMGm3RxP9riUpZbjq-fhkMmgRaGCAvv3LKaYyv8mQ%
> 40mail.gmail.com
> <https://groups.google.com/d/msgid/php-fig/CAGOJM6LqjaMGm3RxP9riUpZbjq-fhkMmgRaGCAvv3LKaYyv8mQ%40mail.gmail.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/CADqTB_jrtoqQxkQGXhLMGhU7KLABb5nbr12q87jiGdy5sOSMUA%40mail.gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to