This post originated from an RSS feed registered with Ruby Buzz
by Christian Neukirchen.
Original Post: Introducing Rye
Feed Title: chris blogs: Ruby stuff
Feed URL: http://chneukirchen.org/blog/category/ruby.atom
Feed Description: a weblog by christian neukirchen - Ruby stuff
After trying almost every web framework for Ruby out there, I still
could not find one I really liked (Wee was close, but has non-restful
URLs), so I simply decided to grow my own (hey, you know me ;-)),
called Rye.
Rye is a framework of the different kind. I don’t have a lot of code
yet, and lacks a lot of functionality, but I could extract the basic
idea already and will try to explain it here.
Rye provides an RESTful interface to stored objects. So far, my
objects are simply stored as YAML files, but that will not scale for
bigger amounts of data. Rye maps these objects onto URLs like this:
So far, Rye can handle the two most commonly used (and supported,
sigh) HTTP methods, GET and POST. In the case of GET, Rye will
retrieve/load the object, call the method on it (possibly with the
arguments and the parsed query) and, depending on the return value
of the method, render the generated page or call show, the default
renderer for the object. POST is treated similary, except that the
object is saved to the store again before rendering the site.
Therefore, GET can’t easily change any values and is idempotent, as
required by REST. (Of course, you still can—and are free to—shoot
yourself in the foot by manipulating the storage on your own, but it
will really be your fault.)
The nice benefit of this is that there is not much to do to use Rye:
Usually (so far, at least) you simply define a few YAML specific
methods to store only the required instance variables of the object
and make your class inherit from Rye::Base, which defines a few
helper methods and attributes (maybe this should get a mix-in).
As an example, I developed a very simple to-do list manager:
class ToDoList < Rye::Base
attr_accessor :title
attr_accessor :todo
attr_accessor :done
def initialize(title)
super()
@title = title
@todo, @done = [], []
end
def to_yaml_properties; ["@title", "@todo", "@done"]; end
def show; template; end
def add(params); @todo << params["item"]; self; end
def finish(item)
@done << item if @todo.delete item
self
end
def undo(item)
@todo << item if @done.delete item
self
end
end
As you can see, this is straight-forward Ruby code without any Web
specific stuff—except maybe the show method that calls template,
a helper defined in Rye::Base that renders the object using a
class-specific Kashmir template (of course, you can easily interface
with your favourite templating engine).
If you wonder why finish and undo return self, well, that means
that Rye will redirect to show them, a useful and logic convention.
finish and undo do change data, and therefore need to be called
using POST. As of now, you would call finish("blubb") by writing HTML
like this:
Since the code essentially only contains the real application logic,
it is very easy to unit test. In fact, you test it just like any other
class. (Nevertheless, I may add a helper library for unit testing
which I dub “ergot” :-))
So far, Rye is only about 150 lines of code, but already covers a lot
of the basic functionality. I’ll need to add a generic store, so one
can use databases (for example with Og) too and isn’t forced to use
YAML. Maybe I get a first release done this week (or possibly not,
who knows).
I’d be interested in hearing your comments on Rye, just comment here
or mail me.