Granted, I haven’t been spending all my time looking at everyone’s favorite framework, but from the ones I do know about, it seems really odd that we have an impedance mismatch between HTTP and the classes/methods we use in our framework. I want to spend a few posts exploring how I think a framework should be put together, so that it conforms as much as possible to REST. My code samples will be in Ruby, but I don’t see any reason why you can’t build this in any other language.
Naturally, I start where the HTTP request gets handed off to what we think of as the controller in most frameworks. It seems as though we ought to have a superclass that defines the uniform interface. It would look like this:
class HTTPResource
def get; end
def post; end
def put; end
def delete; end
def method_missing m
@status = 405
"Method Not Allowed"
end
end
With it, you would instantiate the resources you want to expose. In this case, I want to build, um, how about a Media Release administration tool, where you can add, edit, and post PRs. Let’s expose a resource called Release
.
class Release < HTTPResource
def get; end
def put; end
def delete; end
private
def post;end
end
Well, I’m sure you’re tempted to say that you can post
a Release
, and I’d agree with you, but I wanted to set it up this way to show you something cool: by making post
private, any calls to that method would instead be handled by the superclass’ method_missing
method, and return a 405 Method Not Allowed. Wow, that’s convenient.
There’s a lot of stuff missing. HTTPResource
really ought to get some context together, like a collection of HTTP headers and ready access to query variables. I haven’t yet thought about how that’s going to work yet – it could be that we need instance variables, or it could be that we need classes.
But one thing I thought was pretty cool about this is that this structure seems so simple and natural, you could easily write a commandline script that included these class definitions, and manipulate your app as easily from a script as from a browser. I’m sure you could do it with other frameworks too, but it looks obvious how you’d write such a tool. That seems like a win when it comes times to write tests – just call Release.new.get
, for example, and test what gets returned.
Copyright © 2009
Robert Hahn.
All Rights Reserved unless otherwise indicated.