radarphp / Radar.Adr

The Action-Domain-Responder core for Radar.
MIT License
55 stars 7 forks source link

Is Radar Stack compatible? #5

Closed shadowhand closed 9 years ago

shadowhand commented 9 years ago

I'm unclear if Radar is Stack compatible or not. It seems to have a concept of middleware, but nothing specifically mentions Stack support.

pmjones commented 9 years ago

My understanding is that Stack is centered around the Symfony HTTP kernel; if that understanding is correct, then the answer is "no". Radar is PSR-7-compatible (compliant) instead. Does that answer your question (even if it's not the answer you'd've preferred) ?

shadowhand commented 9 years ago

That's a correct assumption... is there any particular reason that Radar choose not to use Symfony HTTP kernel? Is there a fundamental conflict between choosing PSR-7 and HttpKernelInterface?

I'm trying to get a clear sense of how Radar fits into the current landscape, since it doesn't seem to be focused on allowing component swapping to the same extent that a Stack-compatible framework would.

What I'd really like to do is use Radar with a different router, but right now it seems the coupling makes it very hard to do so, most likely because of the Router/Dispatcher separation in Aura.Router.

pmjones commented 9 years ago

is there any particular reason that Radar choose not to use Symfony HTTP kernel?

Other than "Paul doesn't like the Symfony HTTP kernel", no.

Is there a fundamental conflict between choosing PSR-7 and HttpKernelInterface?

(/me furrows brow) They have greatly different interfaces, and of course you can't typehint against both, so that seems like a fundamental conflict to me. However, I confess it never occurred to me that Radar might "do" both of them somehow. Did you have some ideas here?

I'm trying to get a clear sense of how Radar fits into the current landscape

It's a little at-the-boundaries-of the current landscape. PSR-7 got accepted yesterday (not even 24 hours ago at this point). That means Radar is, depending on how you feel about PSR-7, either on "the leading edge" or "highly experimental." I think it's the former, but then, I would.

it doesn't seem to be focused on allowing component swapping

Since the "handlers" can be replaced entirely, the components are definitely swappable. Cf. https://github.com/radarphp/Radar.Project/blob/1.x/docs/handlers.md

What I'd really like to do is use Radar with a different router

Totally do-able, provided you use a PSR-7 message set and not a Symfony-specific HTTP message set. Cf. the bits about RoutingHandler in the "handlers" link above.

it seems the coupling makes it very hard to do so, most likely because of the Router/Dispatcher separation in Aura.Router.

Yes, the dispatching is a separate thing, even in Radar. The real action (heh) there is in the RoutingHandler and in the ActionHandler. If you look at those, you may find a way to make it more amenable to your desires, in which case I'd like to hear about your findings.

shadowhand commented 9 years ago

Thanks for the clear response. I don't have any specific examples of how things could be done, as I've just seen Radar less than an hour ago. It's definitely very interesting to me, and I think ADR is a great pattern, so I will continue to dig into it and perhaps have some suggestions in the (near?) future.

pmjones commented 9 years ago

I really appreciate your clear, concise, and especially civil criticism here. (Not that you yourself would do otherwise. ;-) I'm very interested to hear your suggestions as you have them. Thanks!

shadowhand commented 9 years ago

One last thought I have... your implementation of middleware would be vastly improved by using this signature (which comes directly from Stack concepts):

function(Request $req, Response $res) {
    return $res;
}

What this allows you to do is modify (or more accurately, replace) the response during the middleware lifecycle, instead of using pass-by-reference manipulation, which is (imo) a bit of anti-pattern.

I do realize this is (more or less) in direct conflict to the current vision of middleware, but I think that Stack has very clearly proven the benefits to using this pattern.

pmjones commented 9 years ago

Ah so! The pass-by-reference thing is a compromise, and I'm not terribly thrilled with it either. Here's the deal:

Right now, if middleware returns a Response, that signals Radar to do an "early exit" and skip ahead to the sending phase. Radar replaces the existing Response with the returned one, and sends it. If middleware returns a Response as a matter of course, we'd need a different way to signal an "early exit" from middleware. I am open to suggestions here.

Likewise, because Request and Response are immutable, we need a way to share modifications with the next middleware and with the Action+Responder logic. Allowing the optional use of a reference to the Request and Response subverts the immutability to allow that kind of sharing. As with the "early exit" problem, I am open to suggestions here too.

shadowhand commented 9 years ago

I don't think there is an early exit "problem", per se. If the request should abort, it should be aborted with an HTTP-specific Exception that will be handled by injecting a response. Again, I think Stack has this particular pattern perfected, which is one of the main reasons I opened this issue (though it took me a while to work through it mentally).

pmjones commented 9 years ago

Hm, or returning an "EarlyExit" object of some sort. (I'd like to avoid using exceptions for flow control if possible.) Let me see what I can do there. If you like, open a separate issue with that suggestion specifically, otherwise I can reference this thread.

shadowhand commented 9 years ago

@pmjones #6.

shadowhand commented 9 years ago

@pmjones maybe we can collaborate on this?