
Roda – A new Ruby web framework - sebkomianos
http://roda.jeremyevans.net/index.html
======
UUMMUU
The problem with this approach is readability. If you look at the code vs
Sinatra every time you want to figure out which route to edit, you have to
traverse the tree as opposed to just scanning for the route you want. As an
example, editing the route /artist/:id/album/:number requires you to first
find the /artist/:id then scan down and look for /album/:number making sure
you watch for the closing end because what if the route isn't defined? In
Sinatra, you look for /artist/:id/album/:number. The solution to this is to
put a comment on every route to denote where it is. I agree the tree
methodology can be faster O(log N) (for GET and POST) vs O(N) but readability
suffers with no comments.

~~~
ehm_may
Why couldn't Sinatra create some sort of underlying tree structure that could
perform in O(log N) as opposed to O(N). That way you get the readability with
the perf.

~~~
vidarh
It couldn't create a tree in all instances because it allows full regexes in
the routes. It could create a hybrid (split into trees for anything with a
known static prefix), or go the full hog to a finite automata, though. But at
least the latter is suddenly a big complexity increase.

------
jeremyevans
I'm glad Roda is finally getting some publicity. I submitted it here when it
was released.

I've converted about 15 apps from Sinatra to Roda, and a couple of Rails apps
to Roda (working on converting my final Rails app). Personally, I've found
that the biggest advantages come when the URL structure mirrors your
application structure, and you have redundant code in many routes, as that
type of code becomes simpler, faster, and DRYer with Roda.

Yes, you can use a before block with wildcard routes with Sinatra, but Sinatra
will still traverse the routing list sequentially and recheck the full route
for every entry in the list. Unfortunately, while I love Sinatra, have
contributed patches to it, and have used it since 0.1.0, the approach doesn't
scale well for sites with a lot of routes.

The code non-locality issue shouldn't be ignored, and is probably the largest
issue with Roda, but the issue is probably going to happen with any approach
that DRYs up the code to the same degree. It's true if you use a before block
in Sinatra, or a before_filter in Rails.

The use of a routing tree really isn't an innovative approach (at least not
innovated by me). It's been around in Ruby since Rum was released in 2008 (and
maybe earlier elsewhere). However, it's not well known, and I hope that Roda
brings it into the mainstream.

One of the best things about Roda that I don't think has been mentioned in the
comments yet is the plugin system, which I borrowed from Sequel. This makes it
easy to extend Roda beyond its very small core. For example, the multi_route
plugin makes it easy to scale Roda to larger sites by splitting up routing
subtrees into specific files. There are currently about 15 plugins, and I have
ideas for quite a few more that I will implement after finishing up my current
Rails->Roda conversion.

I apologize that the code on the website isn't syntax highlighted. If anyone
can offer their design skills, I would greatly appreciate it.

If you have any questions about Roda, please ask.

~~~
jamesbritt
First: This is pretty sweet, Jeremy. Glad to see this.

Second: How well does it scale for developing large sites (for whatever value
of "large" seems useful for discussion).

One of the things I really like about Ramaze is that I can start with
basically a Rack app, spin it off to a simple Ramaze app, and keep expanding
and refactoring it as requirements call for.

Is there some app size or level of app complexity beyond which Roda would not
be a sensible choice? You say it has a plugin system; is it really battle-
ready? (I'm going to guess Yes because of who wrote it, but I'd like to hear
any additional thoughts on it.)

I get the impression that Roda lends itself to building large sites that are a
collection of sub-sites or services; you're never really building a single big
monolithic app.

Side note: For fast syntax highlighting you could use embedded gists.

[https://github.com/blairvanderhoof/gist-
embed](https://github.com/blairvanderhoof/gist-embed)

~~~
jeremyevans
I don't work on truly huge sites, my largest is only about 10kloc. But it
scales very well for the all of the sites I've tried, and I think based on the
architecture it would scale to much larger sites.

Your workflow with Rack->Ramaze should work similarly when using Roda. Roda
scales down well:

    
    
      # config.ru
      require 'roda'
      Roda.route{'Hello world'}
      run Roda
    
    

There is probably some level of complexity where Roda may not be a good
choice. I'm not sure what that level is, but I don't expect to hit it on sites
I work on. In any case it's probably best to split up such an app into
multiple apps/services before that level is reached.

In terms of battle readiness, it's new and currently I think I'm the only
person using it in production. I hesitate to call something battle ready until
there are more people using it, but I'm very committed to it and you can
expect the same level of support for Roda that Sequel receives.

Thanks for the tip on embedded gists, I'll look into that.

------
swanson
I don't really buy the "big win" over Sinatra ("much DRYer", no need to set
ivars for each action) because you can just use a `before` block with wildcard
routes.

    
    
        before '/artist/:id*' do
          @artist = Artist[params[:id]]
        end
    
        before '/artist/:id/album/:number*' do
          @album = @artist.album_with_number(params[:number])
        end

------
diminish
Welcome Roda and congrats for this new innovative routing idea. As much as I
see some value in a tree-like routing definition in this nice comparison with
Sinatra,
[http://roda.jeremyevans.net/why.html](http://roda.jeremyevans.net/why.html),
Sinatra's routing approach still appears to be more readable and manageable.
Maybe Sinatra could optimize the storage of the routing entries internally in
a tree to make it as fast as Roda (if it doesn't already do).

~~~
Mithaldu
> new

It's not all that new. Subdispatch with anonymous functions has been done
before:

[https://metacpan.org/pod/Web::Simple#DISPATCH-
STRATEGY](https://metacpan.org/pod/Web::Simple#DISPATCH-STRATEGY)

As for readability, Roda kinda shoots itself in the code by not having any
highlighting on that snippet, but generally yes, you want to keep dispatch
trees to small apps. On the other hand, using P/WSGI apps you can stack apps
inside one another, scaling trees without getting a moloch. Not clear on
whether Roda supports that.

~~~
jeremyevans
Roda supports stacking apps via r.run to dispatch to any other rack app. You
can also use the multi-route plugin, which allows you to split up the routing
into subtrees, but keeps the current state.

------
krisdol
I love it. I think the concerns about the code being unmaintainable from the
example are a bit unfair. There is nothing preventing a developer from moving
the blocks out into separate files/classes for a more coder-friendly
organization. How deep do you guys nest your javascript callbacks?

This also lead me to check out sequel, which I can't believe that I'm just now
finding out about.

------
benvds
I'm very fond of his sequel gem. The source is really great just to browse
through and learn from.

~~~
shrekuntu
I agree. Everything Jeremy makes is absolutely brilliant.

------
SeoxyS
I've been using a web "framework" I wrote for a few years now. It now powers
various projects, from the Chartboost Store backend, to the entire the entire
backend codebase for my new startup, FreshPay.

[https://github.com/kballenegger/kenji](https://github.com/kballenegger/kenji)

One of the big things that makes Kenji awesome is that, like Roda, it uses a
routing tree.

------
jasonlfunk
I think this looks great. However, even in his simple example comparing Roda
and Sinatra the code ends with 7 'end's. I can imagine how deeply nested a
non-simple app can be. In my experience, the deeper you get in your nesting -
the more complicated the code is to read.

------
programminggeek
Oh boy another web framework to benchmark... :-)

[http://www.madebymarket.com/blog/dev/ruby-web-benchmark-
repo...](http://www.madebymarket.com/blog/dev/ruby-web-benchmark-report.html)

------
fingerprinter
It might be just me, but that is insanely hard to read. I MUCH prefer the
Sinatra approach for that reason alone. Looking at the examples side-by-side I
couldn't tell what was going on in Roda...at all.

------
james-skemp
My apologies if this is off-topic, but since I see mention of various
frameworks ... it seems relevant.

I'm a .NET dev finally looking at Ruby again. I have a Rails book from a long
while ago that I'm working through (well, planning on - Rails 4 in Action,
still in MEAP) but looking at this data I'm wondering if that's the best idea.

Any recommendations on a framework for someone getting started?

If it helps, I've been using ASP.NET MVC since 1.0 if not slightly earlier.

~~~
jonahx
It depends on your goals, but if they include simplicity I would strongly
advise _against_ rails. Coming from .NET, you may be looking for the breath of
fresh air feeling ruby can provide, that I can now do things in 1 line that
took 5 before and understand every part of my system -- if that is the case,
Sinatra or another microframework might be the thing for you. It's also nice
to be able to learn and start using something in a matter of hours rather than
"working through a book"

~~~
james-skemp
Belatedly, thank you for the suggestion.

It sounds like you may have come into Ruby from a similar background; any
suggestions on a good way to start learning the language? There seems to be an
interesting post on creating a very basic blog engine via Sinatra, but
everything else I've found is ... lacking.

As far as my own goals, I actually like .NET (C#) as a language, and generally
don't feel as though ASP.NET MVC is too complex. It has definitely gotten a
bit more bloated in particular areas, but ... Shrug.

Thanks again!

------
davexunit
I wish that routes weren't stuck within strings like `/artist/:id`, but
instead used some kind of pattern matching like `['artist' :id]`. It's better
to use Ruby syntax instead of a quoted string of characters that can't be
manipulated or verified as easily.

~~~
jeremyevans
You can do r.on('artist', :id) instead of r.on('artist/:id') if that is your
style preference, both work in Roda.

------
thefreeman
Anyone know where the name came from? It happens to be my last name and it's
really amusing me reading the docs and these comments.

~~~
jeremyevans
The name Roda comes from the Ys video game series, in which the Roda trees
play a small role. I'm a huge Ys fan.

~~~
thefreeman
Cool, I may have to check them out. At the least this gives me a reason to
stop putting off learning ruby :)

------
noonat
Definitely feels like an improvement on Cuba! I'm not a huge fan of the `is`
method here, though. I feel like you could get the same thing from a terser
DSL if you treated HTTP methods as terminators and only allowed `on` to filter
the path.

------
farrel
Jeremy Evans ain't nothing to fsck with.

