02 Feb 2006
•
Software Development
Update: Due to a misconfiguration some of my blog entries from the month of Feburary recently lost. This is merely a repost of the original content.
Being
relatively new to CSS I recently attempted to layout a page with a
sidebar to the left of the main content using only CSS. I spent several
hours trying to get this to work to my satisfaction before giving up.
In the end I just added a two column table to encompass the sidebar and
content which works well but makes me feel dirty. That table is
obviously just about layout and therefore should not be in the markup.
While I was on that wild goose chase I complained to one of my friends and today he pointed me to an article that describes one technique for column layouts.
The technique is fairly elegant but it, and all the other techniques I
have seen, have one major flaw. Namely, it requires explicitly
declaring the widths of the columns.
Any techniques that require explicitly declaring the width of a
block level element that will contain text is fundamentally broken. I
say this because it forces you to make a choice with no options. You
can either trust the users configuration and accept that your page is
going to look crappy (lines will get wrapped that do not really need to
be wrapped) for any user that have changed the default values for their
font and font size or you can explicitly set the font in the CSS, in
which case I will curse you every single time I use your website.
These days it seems that web designers generally choose the second
choice, ie explicitly setting the font in the CSS. This is the worst
possible choice. Sure it makes your site look pretty but the world does
not look at your site as if it were a picture. They actually try to
read that text whose size is 4px and in a font that is particularly
ugly on their system. By changing the font, or size, you are forcing
your users into a sub-optimal environment. Not to mention the people
with actual visual impairments.
Anyway, I guess I am just trying to say that I am disappointed with
the current state of CSS. All these kludges that get created just to
account for the fact that CSS is missing the ability to change the flow
direction. Normally, flow for block level elements is top-to-bottom and
that is appropriate most of the time but fairly often you really want
the flow of block level elements to be left-to-right. If we had that
single feature this whole sidebar/column issue would go away.
27 Jan 2006
•
Software Development
I have mentioned it the past that I now to use Ruby for many tasks that in the past I used Bash. Today that happened again. I wrote some little script to create and destroy ssh tunnels. This is pretty straight forward except for one little problem. ssh -fNL … will launch the tunnel and put it in the background after collecting your password, but because the ssh command puts itself into the background $! is not set by the shell. That means that when it comes time to shutdown the tunnel you have to figure out the pid from ps. Writing the ps and grep command to get you the line describing the process of interest is easy and sed can extract the appropriate column value without any problems. The problem is that I have to go searching the Internet every time I use sed because the only command I often enough to remember reliably is substitute.
So today, instead of spending 30 minutes figuring out how to get sed to extract the pid from the ps output I send less than ten writing this
local_port = "55#{port_to_forward}"
if pid = `ps -C ssh -o pid,cmd`[/[[:digit:]]+(?=.*L\s+#{local_port}:)/]
`kill -9 #{pid}`
else
puts "There is no ssh tunnel on #{local_port}."
exit 1
end
Nothing too complicated there but it is a easier for me write than the equivalent sh using grep, sed, etc.
One thing I do want to point out, because it make me giddy every time I use this feature, is the use of a regular expression as the argument to the #[] method. Most other languages in which I have worked supported some syntax like “my string”[2] that yields the character specified by the number inside the square brackets. Ruby allows that usage but, as an alternative, you can pass in a regular expression and the #[] method will return the portion of the string the regular expression matches. So what the “if pid = …” line says is list all the ssh commands running and from that extract first number that is followed by the arguments used to create the ssh tunnel. That first number is always pid of the process that needs to be killed in order to shutdown the tunnel.
One of the things I really appreciate about Ruby is the fact that is useful for everything from 10 line scripts to highly scalable and reliable web applications. That is what I call a general purpose language.
27 Jan 2006
•
Miscellaneous
As it turns out I was able to make to the Denver-Boulder Ruby GroupOr is it Colorado Ruby Enthusiasts (CORE)? meeting last night (thanks for putting it together Marty). It was a stunning success as far as I am concerned. There were, easily, 30 people in attendence, which is quite a bit more than I anticipated. Last night was basically a meet and greet for the Ruby enthusiasts in the area, which I think is perfect for a first meeting.
Planning for the second meeting is already started (apparently it will included some presentations) so if you missed this one you’ll have another chance fairly soon.
23 Jan 2006
•
Software Development
When I started using Ruby on Rails professionally a few months ago I hoped that Rails was first of a new breed of web application frameworks. After working with it for several months I have reached conclusion that it is not the paradigm shifting framework I had hoped for. Rather, it is just an incremental, though significant, improvement to the existing paradigm of web application frameworks. It is significantlyI think the [5-10 time productivity improvements people claim](http://www.onlamp.com/pub/a/onlamp/2005/01/20/rails.html) are probably not far off. less effort to implement a web application in Rails than in any other framework in which I have worked but it is not better than those other frameworks, just easier.
I am an unabashed RESTafarian. I believe that the RESTful nature of the web is what has made it successful. I think that every entity (read: resource) of any consequence in any system should have at least one URI. I believe that RESTful architectures are the best way to produce scalable, flexible and powerful applications. And, sadly, I believe that it is, generally, inappropriate to build RESTful applications in Rails.
The Problem
Rails is fundamentally a procedural framework. You can see the in the default form of the URI it uses, for example, http://example.com/product/show/1, in the names of the methods that get called on the controllers, for example, show, create, destroy, etc, and even what those methods are called, actions. The web is fundamentally not a procedural environment, it is a RESTful environment. However, much like how you can write procedural code in an object oriented environment you can also write procedural code for a RESTful environment, but by doing so you miss many of the advantages of the RESTful environment, which is quite unfortunate.
I am not disappointed by the fact that Rails is, by default, procedural. In fact, for any web application framework to succeed, at this point in time, it must support a procedural approach to web applications. This is because, basically, every mainstream web application framework in existence is procedural in nature. That fact combined with the fact that people will not, usually, adopt a new technology unless the new technology allows them to use their existing idioms more effectivelyI picked this meme up from someone’s blog but I cannot remember whose. If you recognize it please let me know where I saw it so I and link to it. means the any web application framework must support tunneling RPC over the web. Rather, the disappointing thing is that I now believe it is impractical to make Rails behave in a RESTful manner, in the general caseThough, you can reasonably create RESTful interfaces for small parts of an applications..
Initially I thought that RestController
might be a solution. RestController provides a mechanism for easily defining the actions of a controller in terms of the HTTP method used in the request. For example, you might have the following code using the RestControllerAll error handling has been left out for clarity.
class BooksController < RestController<footnote>In reality you would want to modify ApplicationController inherit from RestController, rather than ActionController::Base, and to inherit from ApplicationController so that ApplicationHelper would be included.</footnote>
...
verbs_for :show do
def get
@book = Book.find(params['id'])
end
def put
@book = Book.find(params['id'])
@book.update_attributes(params)
end
end
...
end
This works reasonably well, as far as it goes. Unfortunately, merely respecting the action specified at the protocol level is not sufficient for RESTful behavior. Further, the astute reader will have noticed that the abstraction is starting to leak a little already. If you want to create or update a Book entity you need call the show action. Hardly what you would call obvious.
You can hide this inconsistency from the client with a clever set of routes but you are forced to deal with it inside the application code, and that clever set of routes will cost you. You end up needing a lot of routes and most of them have to be hand constructed. Routes in Rails are pretty easy to create but each custom route increases the cognitive load when trying to understanding the entire system. Worse yet, routes are physically separated from controllers (a sub-optimal design decision in my book) so it can often be non-obvious how a particular controller is called from the outside world. Even given a clever set of routes the URI production mechanisms in Rails force you to acknowledge that the system is procedural by requiring a controller and action be specifiedIf you do not specify them it assumes the current controller and/or action. every time a link is produced.
The problem is an absolutely fundamental one. Namely, Rails equates each URI with as single action and in a RESTful architecture a URI equates to a resource with, up to, four actions. While you can write code in Rails that will do the correct thing the names will never be quite right and you end up maintaining a lot of custom, and non-obvious, code to protect the illusion that your frameworks abstractions match those fundamental to the Web.
A RESTful Future?
There is a lot to like about Rails. It would be nice if we could retrofit RESTfulness onto Rails, but I cannot see an approach that I think would work. However, I am not a Rails expert so I am going to sketch out what I think a RESTful Rails would look like and hope that someone smarter than I will see a way where I do not.
The following code is approximately what I think a really RESTful controller should look like
class BooksController < RestController
uri_base "/books/"
resource "." do
get "application/atom+xml" do
# return XML representation of collection containing all known books.
end
get "text/html" do
# return HTML representation of collection containing all known books.
end
post do
# create new book and add it to the collection
end
end
resource "./:id", :requirements => {:id => /^[[:digit:]]+$/} do
get do
# yield html representation of a individual book
end
put do
# update and individual book resource
end
end
resource "./:id/editor", :requirements => {:id => /^[[:digit:]]+$/} do
get do
# yield a representation of the book editor (a page with a
# form that puts to "./:id" on submit)
end
end
resource "./creator" do
get do
# yield a representation of the book creator (a page with a
# form that posts to "." on submit)
end
end
end
In some was this looks a bit like what the RestController provides but it is vitally different is several ways. First, resources are specified by explicit URI patterns. URIs are a fundamental part of the web and are beautiful and elegant in their own right. There is no reason to hide them. There are some practical concerns with explicit URI patterns but this example avoids those by having all the URI patterns be relative to a base URI pattern specified in the controller. If the controller is moved to another URI it need only be tweaked in one place. Second, action implementation is allowed to vary on URI, HTTP method and requested content type. Varying on content type is basically required for any non-trivial REST application so it should be baked into the framework from the beginning.
Having actions specified by URI patterns means that we would need new URI production mechanisms in Rails. These new URI production mechanisms would take the target controller because, in this world view, URIs are usually relative to a controller. The should also, optionally, take a MIME type.
<%= link_to "I Know A Rhino", :controller => 'books', :resource => './:id', :id => a_good_childs_book -%>
In principle the above is doable, I think. For example, a RestfulController could write new routes based on the resources calls. The code would probably be a bit hairy but the interface could be made pretty clean. And URI production functions would be cake by comparison to the non-RESTful ones. The problems are mostly practical. For example, controllers are currently loaded lazily. They are not loaded until the first time a route to that controller is exercised. This means that you cannot have the controllers add the appropriate routes for the resources they declare. It might be possible to change Rails to load the controllers eagerly but that raises the question of if two controllers URI spaces overlap who should take precedence. I think you would just do last loaded wins but that means that you would need a way to explicitly tweak the load order. And how do generated routes relate to explicitly routes, precedence-wise. I haven’t even really thought about how backwards compatibility with RPC style controllers would be maintained, and that would be absolutely required, or how template lookup would work.
Our Last Best Hope?
I fear that we RESTafarians might have to embrace (and extend) Rails, even though it is not the optimal platform for a RESTful web application framework. The reason is that Rails is really good at, human facing, web applications. I doubt that we will get this sort of productivity compatibility in developing RPC style web applications again anytime soon, if ever. That means that it will be hard to convince the world to embrace a truly RESTful web applicationframework because, even it is great, it will provide only marginal improvements for the RPC web application idiom that people know.
Hopefully someone with more skills and free time than I will take up the challenge of making Rails RESTful framework. Until then I suppose I will continue to write ugly, but functional, RPC style web applications. At least with Rails I do not feel like I am wasting most of my time with administrivia. On the other hand, the lack of administrivia leaves me with more time to feel dirty about the interface I am creating.