[PSR-15] Why StackInterface? And why is it not a middleware?

531 views
Skip to first unread message

Matthieu Napoli

unread,
Jul 10, 2016, 8:41:50 AM7/10/16
to PHP Framework Interoperability Group
Hi everyone,

I had a look at the spec and at the metadocument, but couldn't find an answer to my questions about PSR-15 (HTTP middlewares for those mixing up the numbers like me):

- why are middleware stacks not middlewares too?
- as corollary, why StackInterface exists at all?

interface StackInterface
{
    /** snip< withMiddleware() and withoutMiddleware() > */

    public function process(RequestInterface $request);
}

This looks a lot like the signature of a middleware, except it can't call "next". I've seen scenarios where it might be useful to have a middleware stack inside another middleware (i.e. nested in another middleware stack or router) - here is an illustration: https://github.com/stratifyphp/router#everything-is-a-middleware 

If we consider middleware stacks just like any other middleware, the standard is much simpler and we don't need the StackInterface. It also sounds to me like standardizing a middleware stack is out of scope for a middleware standard.

I did not forget the 2 other methods of the StackInterface: withMiddleware() and withoutMiddleware(). These 2 methods are used for configuration, which is often done by users. I don't see why we would want interoperability at that level. It's like the LoggerInterface doesn't contain methods for configuring the logger.

Cheers
Matthieu

hannesvdreken

unread,
Jul 11, 2016, 3:15:30 AM7/11/16
to PHP Framework Interoperability Group
Hi Mathieu,

the with(out)Middleware methods are what makes up the stack. This is making general, what every implementation has but does differently. Would you agree with me that StackInterface should be at least an extension of the FrameInterface? Like so you can combine stacks in other stacks (without having to use a dumb StackWrapper class that implements FrameInterface).

Matthieu Napoli

unread,
Jul 12, 2016, 10:42:06 AM7/12/16
to PHP Framework Interoperability Group
Thanks for your answer!

the with(out)Middleware methods are what makes up the stack. This is making general, what every implementation has but does differently.

Yes but why do we need interoperability for that? I don't see the need for that (especially in a PSR for a middleware standard), this is not a problem today.
 
Would you agree with me that StackInterface should be at least an extension of the FrameInterface? Like so you can combine stacks in other stacks (without having to use a dumb StackWrapper class that implements FrameInterface).

If middleware stacks or pipes or whatever were middlewares, then it would be easy to combine them. I don't see why we need a separate interface for "something that takes a request and returns a response" when we already have it (MiddlewareInterface).

Matthieu Napoli

unread,
Aug 14, 2016, 1:13:19 PM8/14/16
to PHP Framework Interoperability Group
Sorry for bringing that topic up again but I'll make it clearer:

I think the StackInterface should be removed.

- I don't see what it has to do with PSR-15 (interoperability for invoking middlewares)?
- even if it was a separate PSR, I don't see the problem it is solving (and the META document doesn't help)
- I think the interface itself is very limiting and should be improved (but again, I don't think it should exist at all so…)

Do we have any reason to keep it, or should we remove it?

Alexandru Pătrănescu

unread,
Aug 15, 2016, 3:08:30 AM8/15/16
to PHP Framework Interoperability Group
+1 for removal.
There is really no reason to have it.

The methods for creating the stack are not going to be used against the interface because each library will have it's own way of using it's implementation.
What remains is the process method that I think is also in the same position: you know the implementing class when you call it.

Regards,
Alex

Woody Gilk

unread,
Aug 15, 2016, 8:43:15 AM8/15/16
to PHP Framework Interoperability Group
The reason that StackInterface exists as a "MAY" recommendation is
because it illustrates the requirement that stacks must be aware of
the type hint of the middleware being added to the stack [1]. If the stack
ONLY accepts client middleware, it MUST type hint against
ClientMiddlewareInterface. If it accepts both server and client
middleware, it MUST type hint against MiddlewareInterface.

Now it could certainly be argued that having the StackInterface is out
of scope for the spec and I wouldn't disagree. However, any removal
[2] should be accompanied by an update to the middleware meta document
to describe how the type hints should be used. Personally, I find
having code examples more useful than words, which is why I added the
StackInterface as a "MAY" recommendation.

With regard to having the methods withMiddleware() and
withoutMiddleware() be immutable, I think this is in line with PSR-7.

[1]: https://groups.google.com/d/msg/php-fig/sYecuqdYIkY/PPVL2RDqEgAJ
[2]: https://github.com/php-fig/fig-standards/pull/803
--
Woody Gilk
http://about.me/shadowhand
> --
> 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.
> 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/b9021564-07b1-44fa-ae87-4afb36c6a211%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Matthieu Napoli

unread,
Aug 15, 2016, 8:53:28 AM8/15/16
to PHP Framework Interoperability Group
Thanks Woody for your answer. Such information should be in the META document, else we are bound to discuss all this over and over.

Back to the topic: I don't see how the interface helps. If I'm writing a server middleware stack, I'll type-hint against ServerMiddlewareInterface (and vice-versa if it's a client middleware stack). 

> it illustrates the requirement that stacks must be aware of  the type hint of the middleware being added to the stack [1]. If the stack  ONLY accepts client middleware, it MUST type hint against  ClientMiddlewareInterface. If it accepts both server and client  middleware, it MUST type hint against MiddlewareInterface. 

Right, so how is the interface helping since it's type-hinting against the root "MiddlewareInterface"? It will prevent implementors from type-hinting against a more specific interface so I don't see the point. I'm missing something here.

> Now it could certainly be argued that having the StackInterface is out of scope for the spec and I wouldn't disagree. However, any removal [2] should be accompanied by an update to the middleware meta document to describe how the type hints should be used.

What do you mean by that?

Thanks!
Matthieu

Woody Gilk

unread,
Aug 15, 2016, 9:06:11 AM8/15/16
to PHP Framework Interoperability Group
On Mon, Aug 15, 2016 at 7:53 AM, Matthieu Napoli <matt...@mnapoli.fr> wrote:
> Thanks Woody for your answer. Such information should be in the META
> document, else we are bound to discuss all this over and over.
>
> Back to the topic: I don't see how the interface helps. If I'm writing a
> server middleware stack, I'll type-hint against ServerMiddlewareInterface
> (and vice-versa if it's a client middleware stack).

Ah, but this is exactly the problem I am trying to avoid. A server
middleware stack should NOT type hint against the server interface,
because client middleware is compatible with server middleware, but
not vice versa. This is why we have the generic middleware interface
in the first place.
>
> Right, so how is the interface helping since it's type-hinting against the
> root "MiddlewareInterface"? It will prevent implementors from type-hinting
> against a more specific interface so I don't see the point. I'm missing
> something here.

See above. Again StackInterface exists for illustration only and is
only a "MAY" recommendation, which is entirely optional.

>> Now it could certainly be argued that having the StackInterface is out of
>> scope for the spec and I wouldn't disagree. However, any removal [2] should
>> be accompanied by an update to the middleware meta document to describe how
>> the type hints should be used.
>
> What do you mean by that?

Exactly the scenario that I described above and in the post I
referenced earlier:

If your stack accepts server middleware AND client middleware, type
hint against MiddlewareInterface.
If your stack accepts ONLY client middleware, type hint against
ClientMiddlewareInterface.
If your stack accepts ONLY server middleware, type hint against
ServerMiddlewareInterface. (I've never seen a use case for this.)


I will now self-throttle until tomorrow. Further discussions can be
done via Github PR.
> --
> 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.
> 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/0337e9ae-a8a1-45c3-a84d-02b412534e37%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages