

Strata Web Framework - telemachos
http://stratajs.org/

======
clyfe
I find it similar to connect/express <http://expressjs.com/guide.html> but a
less tasty DSL and nothing new, or am I missing something? I'm sure one
inspired the other since the API is strikingly similar (app.use app.get etc),
strange that no comparison is given. Anyway, kudos to the devs for free
software!

~~~
mjijackson
Thanks! I think if you dig in and actually write something with if you'll soon
see that the differences are subtle, but significant.

------
kainosnoema
To be honest, this doesn't look like much of a web framework. The examples
show views being built up using string concatenation... reminds of my pre-
templating days building snippets for jQuery.

Really though, everything shown can be easily replicated with a bit of Connect
middleware, and it'd be cleaner. I don't see the point?

~~~
skeptical
I would go as far as saying that it does not offer much more than what you can
do with the http module. But if you take away built-in template engines, orm,
active reccord and an CRUD generators (both for web forms and APIs), the same
applies to 90% of the frameworks out there. I work with pretty messy code
bases and every other week find myself wondering if using a framework did
really helped more than it introduced unnecessary code.

~~~
bronson
It lets you choose whatever ORM (Mongoose!), templating (Weld!), and CRUD
routing you want. It's like Rack or maybe Sinatra, but definitely not Rails.

And it's much nicer to use than the http module: layerable middleware,
streaming responses, routing...

~~~
troyk
Granted I blazed through the docs and am not a node expert, but for a
streaming web framework I could not find a reference to streaming responses.
It is very Rackish, all examples I found point to calling callback(200, {},
"Hello world!");

What I don't get, is you have to fight with Rack to get anything close to
async, yet here comes a web framework for an async environment modeled after
Rack, go figure.

I assume (meaning I'm about to make an ass out of u & an ass out of me) the
answer is to pass a stream in place of the "Hello world!" string, but that
would cause hell with any middleware expecting a completed response.

~~~
mjijackson
The Strata spec states that a body may be either a string or a stream. All
Strata middleware that needs to modify the body in some way must account for
this. It's not difficult to do a "if (typeof body == 'string')".

Strata borrows many concepts from Rack, but not the synchronous part. Instead
of expecting your app to _return_ something, Strata gives you a callback that
you can use to serve the response when you're ready.

I admit the manual could probably give a better example of streaming a
response. For now, check out the static file serving middleware
([https://github.com/mjijackson/strata/tree/master/lib/static....](https://github.com/mjijackson/strata/tree/master/lib/static.js)).
You'll see that the response body is simply a readable stream to the file on
disk.

~~~
troyk
Thanks, I get it now. Think I'll go play some SSE with it
[http://www.igvita.com/2011/08/26/server-sent-event-
notificat...](http://www.igvita.com/2011/08/26/server-sent-event-
notifications-with-html5/)

------
moomin
I guess the obvious question is: what does this offer that you don't get from
connect/express?

~~~
bfm
From the official announcement
<https://groups.google.com/forum/m/#!topic/nodejs/fqBTNLwhEAI>

    
    
        The main advantages/differences over Connect/Express at this   point are:
    
        - Patterned after WSGI/Rack. This implies some significant differences in the API.
        - Built on node 0.4; takes full advantage of streams.
        - Built-in support for streaming multipart parsing/file uploading (uses node-formidable's parser).
        - Built-in support for gzip encoding, URL rewriting, and URL mapping.
        - RFC-compliant support for content negotiation using the Accept, Accept-Language, Accept-Encoding, and Accept-Charset HTTP headers.
        - A specification with middleware to enforce it.

~~~
dreamdu5t
So nothing? Streams, multiparts, gzip, that is all in Connect/Express. I'm
sorry but adhering to some spec that few people use or care about is hardly an
advantage over Connect. Wouldn't it be trivial for Connect to adhere to the
spec anyways?

tjholowaychuk has done extensive testing/benchmarking of Connect/Express. I'd
really like to see some benchmarks and code coverage.

------
Roboprog
I'm still pretty new to the _idea_ of node.js, but a couple things stand out
to me. This framework uses a session cookie as a way to store some data, not
just as a user/session id/authentication. Thus, they seem to be strongly
pushing you towards an external session store such as memcached or a database.
(I suppose that is an inherit limitation of node.js, at least as commonly
used)

From what I understand, a Node/V8 instance really only utilizes a single CPU,
yes? As a request does I/O, some other piece of code is executed until (some
time after) the async I/O completes. A CPU can be effectively timesharing over
several pseudo-threads, but to use a SMP chip/server, you have to run multiple
instances, with a front-end load balancer. I guess this would drive one
towards an external session data solution, barring some kind of sticky session
and a reason to _be_ sticky.

~~~
bretthoerner
Isn't an external session store practically mandatory regardless of your
backend?

I'm no fan of Node, but even if you have $100k machine running the JVM with a
thousand threads you will (if successful) eventually need a second machine,
and a third, etc. Not to mention persistence (what if you need to restart the
app server?).

Sessions belong in a database of some kind unless you can get away with signed
cookies.

~~~
mahmud
no it's not mandatory. We use Play and it's super stateless. nothing more than
client side cookies. forced us into scalable, share nothing design. love it!

<http://playframework.org/>

for java and scala

~~~
SkyMarshal
The Lift web framework does this too, as does Apple's Web Objects. David
Pollack, creator of Lift, wrote a good explanation of the benefits on Quora,
will post it shortly.

~~~
SkyMarshal
Can't edit my post, so here's David's case (in comments under Jackson Davis's
answer):

[http://www.quora.com/What-are-the-advantages-and-
disadvantag...](http://www.quora.com/What-are-the-advantages-and-
disadvantages-of-writing-a-web-app-in-Scala-using-Lift)

 _"In practice, scaling a Lift site is much much easier than scaling a LAMP
site. Why? Well, state exists someplace. If it exists in the JVM, you get a
lot of performance benefits and stability as well as, in Lift's case, lots of
security. Contrast that with sessions in memcached. "Whoop, memcached went
down, there go a pile of sessions." "Whoops, we've got a new memcached hashing
algorithm, there go all the session." "Whoops, Google just crawled us creating
200,000 new sessions pushing all the but the active sessions out of cache."
"Whoops, the Ruby runtime just went wild, ate all the VM on one of our boxes,
memcached went down..." So, you try storing sessions in some wacky shared
version of MySQL. This solution requires tons of hardware and a team of make
sure that the sharing code is correct, etc. Contrast that to using Nginx,
Jetty and session affinity. It's about 4 hours of setup time and it just
works. See<http://blog.harryh.org/post/7550..>. So, talk to a Facebook
engineer about the challenges they go through to manage state between the
front end, memcached, MySQL, etc. Compare that to Twitter with the famous fail
whale. Compare that to Apple's store and the iTunes store which are written on
WebObject (which is highly stateful.) Lift apps running at scale typically
require 7% of the front end resources of LAMP app. The Lift apps that are
running at scale (Foursquare and Novell pulse are two) do not have the kind of
scaling issues associated with LAMP sites that have similar traffic patterns.
Scaling with Lift is neither tricky, nor risky. It's simple. It's known. It's
proven. Scaling with LAMP is playing whack-a-mole with state and that only
becomes a problem at scale."_

~~~
bretthoerner
I'm confused, are they saying Twitter etc have scaling problems because of
sessions?

Sessions are just about the easiest thing to scale. What am I missing here?

------
joeyespo
At first glance, looks like it's a Flask for JavaScript.

~~~
mjijackson
At this point I'd actually compare it more closely with Werkzeug
(<http://werkzeug.pocoo.org/>).

~~~
joeyespo
Yeah, you're right, there's no built-in templating in this.

------
tlrobinson
It's unfortunate this doesn't just use JSGI, which is much closer to Rack/WSGI
than Connect, and has a fair amount of usage in Node
([https://github.com/joyent/node/wiki/modules#wiki-
middleware-...](https://github.com/joyent/node/wiki/modules#wiki-middleware-
jsgi)), as well as other server-side JavaScript platforms (Ringo, Akshell,
Pintura, Narwhal)

I'd love to hear the reasoning for the differences between the two.

(Disclaimer: I started JSGI)

~~~
mjijackson
JSGI is not able to take advantage of node's ability to serve responses
asynchronously because the spec doesn't allow for it. JSGI specifies that the
return value of an app must be the [status, headers, body], whereas Strata
specifies that the return value of an app is not important and that the app's
callback should be used to serve the response instead.

This is an API incompatibility that cannot be ignored. The most developed lib
I've seen up to this point to get JSGI working on node
(<https://github.com/kriszyp/jsgi-node>) isn't able to get asynchronous
responses working properly. Instead, it just does a body.forEach (see
[https://github.com/kriszyp/jsgi-node/blob/master/lib/jsgi-
no...](https://github.com/kriszyp/jsgi-node/blob/master/lib/jsgi-
node.js#L167)) to write each piece out to the response synchronously.

Copied and pasted from <https://github.com/mjijackson/strata/issues/2>.

~~~
olegp
My JSGI implementation in Common Node (<https://github.com/olegp/common-node>)
uses node-fibers allowing it to stream out responses without blocking the
event loop.

In fact, by connecting an input stream to an output stream (forEachable
objects), the underlying code automatically enables Node's pipe like behavior.

Check out this example: [https://github.com/olegp/common-
node/blob/master/examples/ht...](https://github.com/olegp/common-
node/blob/master/examples/http.js)

~~~
mjijackson
Even so, this breaks down with JSGI middleware that depends on running in a
Java environment. For example, JSGI's gzip middleware uses Java's byte
buffers.

~~~
olegp
Which JSGI gzip middleware are you referring to? It should use portable
CommonJS Binary objects, which in Common Node's case wraps Buffers and in
RingoJS (Java) byte arrays.

------
pkulak
A callback just to get the request parameters out of the environment? What
could they possibly be doing in there that blocks?

~~~
mjijackson
Parsing multipart requests and saving uploaded files to temporary files on
disk. Large request bodies emit data multiple times.

------
frenchfries
looks pretty cool to me, nice job

------
wavephorm

      Server	nginx/0.7.67
    

I can't tell if it's the case here, but I get a little unnerved when a web
framework doesn't even use it for their website.

~~~
RyanMcGreal
They're two different use cases. If I invented a new kind of rocket, I
probably wouldn't use it to go to the store and pick up milk.

~~~
thirteenpixels
Unless you really needed milk...

------
foobarbazetc
performant is not a word.

