

Why your web framework should not adopt Rack API - carlosgaldino
http://blog.plataformatec.com.br/2012/06/why-your-web-framework-should-not-adopt-rack-api/

======
andrewvc
This can be worked around with stuff like rack-stream
(<https://github.com/intridea/rack-stream>)

I'm the maintainer of a similar project for clojure called noir-async. Noir is
built on ring, clojure's version of rack, and has no notion of streaming
responses, but adding it in wasn't a problem at all
(<https://github.com/andrewvc/noir-async>).

In other words, it's not a big deal. Most streaming code should really be a
separate app anyway. Apps that deliver true streams probably need different
infrastructure from say a rails app. You want a separate process running a
reactor to handle concurrent IO.

~~~
jerf
"Most streaming code should really be a separate app anyway."

A great deal of the reason you are saying that is because it's too hard to do
anything else today. That doesn't make it the right answer.

It is far easier to take a fundamentally-streaming stack and layer
conventional request-response on top as a special case than it is to take a
conventional request-response stack and layer a stream on top of that. It
isn't even that much harder to do it right if you start with that from day 1,
but I've had a devil of a time convincing anyone in the early phases of web
framework development of that. ("Why don't you do it yourself?" I'm full up
for spare time projects at the moment... and also, I'm really trying to resist
adding yet another web framework to the world.)

Of course sometimes the right answer really is a separate app. But you should
do that because it's the right answer, not because your stack forced you to do
it that way.

~~~
ianb
"It is far easier to take a fundamentally-streaming stack and layer
conventional request-response on top as a special case than it is to take a
conventional request-response stack and layer a stream on top of that."

This is demonstrably true in that Rack/etc are themselves almost always built
on top of conventional socket-based streaming APIs. Streaming APIs have been
the norm, and yet people choose to put abstractions on top of them. Why?
Mostly because it gives substantial improvements to application code, and
turns the system into more of a set of contracts and less of a mushy touch-
any-object-you-want system, which I think is fundamental to how streaming
works, due to its imperative nature.

Using Rack or any of its equivalents, it would be fairly easy to allow a hole
to be punched through the system to give a direct socket streaming API. Just
toss the relevant objects into the request. It would violate the abstractions
of Rack, any middleware, etc. But you can do it, and it would be easy. It's
not unlike using Rack instead of the abstractions Rails puts on top of it –
arguably it can be useful shortcut parts of the stack.

Why don't people do this? Mostly because no one cares to. It's not that useful
or interesting or testable. It's noticeable enough that people complain about
it, but not noticeable enough to be worth it to take the hit and use a more
imperative API.

~~~
jerf
I would submit you also have the causality backward and are also talking about
the results of the current factoring, not the cause. It is definitely not true
that you have a choice between response/request and an abstractionless
formless mass of a socket. I offer you XMPP as one readily-available
counterexample. HTTP itself, if properly and fully implemented, is actually
another. It worked itself into a streaming protocol, and many frameworks never
noticed. This is part of the reason this cheeses me off so much, because even
the putatively-HTTP frameworks can't actually speak the fullness of HTTP. Oh,
and good luck supporting the full range of SPDY in your request-response
framework.

The idea that streaming can't have abstractions put on it is beyond bizarre.

------
jonsmock
Nice article, Jose!

For those interested, Aaron Patterson (tenderlove) talks about this in his
RailsConf talk, starting at 26:45.

<http://www.youtube.com/watch?v=kWOAHIpmLAI>

------
tlrobinson
One approach we've experimented with in JSGI is a similar API to Rack but with
the addition of promises to add an asynchronous mode of operation. It's
theoretically elegant, but a bit awkward in practice.

~~~
sirclueless
Theoretically elegant, the best kind of elegant.

------
ricardobeat
<http://stratajs.org/> is a nidejs framework designed to take advantage of
streaming. It still uses a rack-like API though.

