Settings

Theme

(fab) - A pure javascript DSL for building async web apps

fabjs.org

86 points by tr4nslator 16 years ago · 26 comments

Reader

tr4nslatorOP 16 years ago

Hey all,

I just launched a dead-simple web framework on top of node.js. It uses (abuses?) a lot of the dynamic nature of javascript to create a jQuery-inspired DSL that's pure javascript, allowing you to create really concise web apps like this:

  ( fab )
    ( "/time", function(){ return "the time is " + (new Date).toTimeString() } )
    ( "/date", function(){ return "the date is " + (new Date).toDateString() } )
  ( fab )
I'd love to hear any feedback from the folks here, so check it out and let me know what you think.
  • mmastrac 16 years ago

    I did a double-take looking at that syntax. I assume that fab (and all of the other bracketed expressions) return functions that chain together? Pretty ingenious. Plus you can detect the end of the chain when one of the methods is passed in "fab" again.

    I think I can say that this is the best (ab)use of the syntax I've ever seen, well done. :)

    • tr4nslatorOP 16 years ago

      Yeah, a (fab) function just returns itself. It's like jQuery's chaining, but using argument signatures instead of object methods to delegate work. The last (fab) is just a way to indicate the chain is over so that a listener can be returned, and has the additional benefit of making it look declarative.

    • netghost 16 years ago

      Thanks for pointing that out, I've been sitting looking at how that could possibly work for a while.

  • jerf 16 years ago

    The problem I've had with writing stuff like this is that if you go too far out of your way to hide the fact that this is still just Javascript, you get a lot of people who don't realize that it is just Javascript and you can do what you want.

    What if you want to dynamically create stuff? You can take the value of fab, use standard for loops and if statements and whatnot to apply things to it, then call fab again at the end and it'll all work fine. By hiding in a DSL here, you encourage people to not realize that, and take away the ability for these people to use the Javascript they already know to build the system. Another manifestation of this general principle is that you may get people who don't realize that they can define a function elsewhere then include it as an argument.

    Please don't laugh or tell me this is impossible. I used to think that too. Experience has bludgeoned me over the head on this, rather against my will.

    Magic really ought to be reserved for things that can't be done without magic. Method chaining is becoming a standard JS technique (even though I don't like it, for pretty much this same reason albeit more weakly as it is less of a departure) and I don't see a reason not to just use method chaining here.

    If I don't miss my guess, as you develop this you're going to miss having it anyhow and have to switch to it anyhow. You're almost certain to end up having more than one type of thing go in those arguments, and the alternative will be either returning to method chaining, or using the first argument to do nothing other than switch on which method you actually call. (And that is honestly just silly because the language already has perfectly cromulent facilities for doing that.)

    • tr4nslatorOP 16 years ago

      I actually think this is less magical than most approaches, since there's no pre-compilation or "with" scoping magic. Sinatra's hello world is awesome, until you realize that a lot of the cool stuff is scoping magic that you have to throw out when your app has to play nicely with others.

      My original approach for (fab) was like jQuery:

        fab()
          .find( path )
            .bind( method, handler )
            .find( subpath )
              .bind( method, handler )
            .end()
          .end()
        .end()
      
      but I realized that I could simplify things by getting rid of methods entirely, and reserving methods for HTTP methods and status codes.

      As for people not realizing they can define functions outside of the DSL, I'm hoping that the extensibility of middleware will mitigate that, just as the ecosystem of plugins did for jQuery.

  • z8000 16 years ago

    The syntax looks cute for one-lined request handler functions. I wonder how it stacks up for larger, multi-line functions. Heck, you're pretty close to sexps (I kid!).

  • malvim 16 years ago

    I had taken a look at it before, and was wondering: Is there a way we can do long-polling stuff with fab?

    (by "long-polling stuff" I mean deferring response.finish())

  • naturalethic 16 years ago

    Excellent work.

cmelbye 16 years ago

What's the ratio of node.js web frameworks to sites that actually use them?

  • netghost 16 years ago

    100:0 From what I can tell, but that being said, they're all coalescing into something interesting.

    • cmelbye 16 years ago

      Exactly what I'm thinking also. There are a plethora of frameworks, but they all bring something cool to the table. I'm still wondering how viable it is for web development, however (just because of how it hasn't really caught on yet while having many chances to.)

      • thenduks 16 years ago

        I think it hasn't caught on yet because there's no (last time I was around anyway) solid, decent, recommended deployment strategies.

        It was once suggested to me on IRC to use only one instance of a node app because it's "non-blocking"... I'm serious: "why would you need more than one?".

        Obviously you can deploy well enough using a monitoring app to keep up as many workers as you want, but compared to stuff like passenger it's just not mature enough.

  • jazzychad 16 years ago

    I use nodewiki [http://github.com/gjritter/nodewiki/] and nerve [http://github.com/gjritter/nerve/] to power my personal wiki/mindmap sites, and I'm also using node to power the backend of a site that should go public very soon.

  • mhansen 16 years ago

    Companies using node.js: http://wiki.github.com/ry/node/

uggedal 16 years ago

Unfortunate name: The Fabric Python deployment tool uses the fab binary and uses fabfiles for configuring deployments: http://docs.fabfile.org/

amix 16 years ago

Stuff like (fab) and CoffeeScript* show how easy it is to build on top of the V8 and node.js platform. And these toy languages/frameworks also have great perfomance given the non-blocking nature of node.js and the optimizations of V8. Amazing and happy to see more of these projects :)

* http://jashkenas.github.com/coffee-script/

  • boucher 16 years ago

    CoffeeScript is a language. It doesn't run natively on node.js, so I don't really see the relationship here.

    • tr4nslatorOP 16 years ago

      Indeed, CoffeeScript was built on Ruby, and its REPL on Narwhal.

    • extension 16 years ago

      Here's a relationship: if I was going to write all my web apps in JavaScript, I would want something like CoffeeScript to ease the pain.

    • amix 16 years ago

      CoffeeScript compiles to JavaScript and it can run natively on V8/node.js (since V8/node.js executes JavaScript)...

Keyboard Shortcuts

j
Next item
k
Previous item
o / Enter
Open selected item
?
Show this help
Esc
Close modal / clear selection