28 Mar 2006
•
Miscellaneous
•
Personal
Have I mentioned lately that I hate house shopping. Actually, maybe it is house selling I hate. Either way I will be very, very, very happy when this moving thing is over.
Our second potential house feel through other the week-end. It was a plain house that backed to a nice park in the burbs. The location was great but house was only okayThe inside had a lot of
potential but the outside was just boring. The inspection came up with $15-20k worth of improvements that would need to be done pretty quickly so I think we are done with that house. We need a project house because DIY home improvements are our hobby, but that is a little too much.
We have only been on the market for three weeks but I am exhausted. I really don’t want to own two houses at the same time, but it might be worth it to have a place that we did not have to clear out of every evening so it can be shown to perspective buyers. Finding a house was so much easier last time (you know, when we were living in an apartment and did not have any kids).
Catherine has found some more house that look good on paper so we are off to see another potential is just a few minutes. Hopefully this one will be the one. Unfortunately, this one is not near a park at all, but it looks nice.
27 Mar 2006
•
Software Development
Charlie has released his take on a RestController
for Rails.
That is very sweet. It is great to see more work on RESTful Rails. It seems to me that each attempt gets closer to an approach I could believe in and be proud of. And, I get a warm fuzzy feeling any time I see a domain specific language developing. The resource
handler Charlie has created is definitely part of a DSL there.
He brings up a few issue that result from his implementation. Some of which are important and some, IMHO, are not.
Leaky Abstractions
Charlie points out that the abstractions start to leak a little when you get to creating the views for a RestController
.
The main issue is the method renaming. You have to know about it since you need to create templates called get.rhtml, get_member.rhtml, etc. It also comes into play if you want to turn on or off filters.
That is very unfortunate. The easiest way to solve this problem might be rethink what makes up a controller. The RestController
design seem intent on combining the functionally of a cluster of related resources. In the example he provides the ProductController
support interaction with the following resources
* every known product * the collection containing every known product * an editor for product resources * a creator for product resources
This set of resources are very cohesive and quite coupled to one another so combining them into a single controller is reasonable. But it causes this problem that you have know that the RestController
is going to take
resource :Member do
def get
#..
end
end
and turn it into an action named get_member
.
Perhaps it would be better to conceptualize a controller as a bit of code that mediates interaction with exactly one type of resource. With this view of the world you would end up with more, smaller, controllers. Charlie’s product example would look more like
class ProductController < ApplicationController
include YarController # that's YetAnotherRestController
verb :get do
@product = Product.find(params[:id])
end
verb :put do
@product = Product.find(params[:id])
begin
@product.update_attributes(params[:product])
flash[:notice] = 'Product was successfully updated.'
redirect_to :id => @product
rescue => e
# Send the current invalid values to the editor via the flash
flash[:product] = @product
redirect_to :resource => :editor, :id => @product
end
end
verb :delete do
Product.find(params[:id]).destroy
redirect_to :id => nil, :resource => nil
end
end
Class ProductsController < ApplicationController
include YarContoller
verb :get do
@product_pages, @products = paginate :products, :per_page => 10
end
verb :post do
@product = Product.new(params[:product])
begin
@product.save!
flash[:notice] = 'Product was successfully created.'
redirect_to :resource => :collection
rescue => e
flash[:product] = @product
redirect_to :resource => :editor
end
end
end
And so on… The main benefits of this is that the template to rendered for a get of ‘http://mystore.example/product/243’ is ‘apps/view/product/get.rhtml’ and, I think, the issues with filters go away, too. The down side is that you end up with four controllers for each basic type of resource you expose. One for the basic resource type you want to expose, one for the collection of all of those basic resources, one for the creator resource and one for the editor resource. I don’t know if the extra boiler plate code is worth the benefits but it feels like it might be.
PUTs and DELETEs
Charlie also points out
a pure REST solution does not work with HTML forms since browsers don’t support PUT and DELETE
He is absolutely correct. However this tunneling PUT and DELETE over POST kludge does not bother me very much. I will now take a moment to revel in being more pragmatic than Charlie, quite possibly for the first time since I meet him seven years ago. Anyway, it is ugly that HTML does not support PUT and DELETE but still very workable.
Handling Bad Data
Finally there is an issue with handling failed attempts PUT/POST. This is the one that bothers me the most. It is not really all that bad from a pragmatic standpoint, storing this info in state works fine. However, it implies a certain weakness in my world view because I did not see it coming.
If the post fails we have to store the ill-formed product into the flash and redirect back to the editor since its at a different URL.
The fundamental problem here is that the separate editor resource will PUT the modified resource when you click save/submit. But what if you messed it up and, say, violated the business rule that blue products must have a price that is divisible by three? In a normal Rails app that proposed change would fail validation and the update action would just re-render the edit page with bad fields highlighted. But in a RESTful world the editor and the validation code are separate and it is wrong from REST stand point to just render the editor resource from in response to a product resource request. However, if you don’t do that you need to get the form data, and which fields are bad, from the previous attempt so that you can re-render the editor with the information the user previously entered and what was wrong with it.
One way you could solve this problem is to allow the creation of “invalid” resources. For example, you require a product to have a description. However, you receive a POST to ‘http://mystore.example/products’ without a description. You could issue the product an ID and store it in it’s invalid state (without a description) and then redirect the browser to the editor resource for that newly created, but invalid, product. That feels really clean from a design stand point but I am not sure how difficult it would be to implement. And you would certainly end up to permanently invalid resources, which might be hard to manage in the future.
21 Mar 2006
•
Miscellaneous
Charles Savage has started a blog. Finally. I worked with, and for, him at Smallworld, and then General Electric. He is wicked smart and usually a bit ahead of the curve. I definitely look forward to hearing more of what he has to say.
16 Mar 2006
•
Software Development
JavaScript ShellVia \[Sam Buchanan\](http://afongen.com/blog/)
I am always going on about how much I like irb, and interactive language shells in general. Now I have one for JavaScript too. That is just cool.
16 Mar 2006
•
Miscellaneous
If you are reading this your looking at my shiny new hosting. I finally had to leave shieldhost because their support was simply inadequate. It took a long time (days usually) and I had to explain the issue multiple times for almost every single ticket I submitted. And then yesterday my host ran out of space in the tmp directory which caused my blog to be down for most of the dayWordPress queries the database in such a way that it often has to write the data to disk due to the size.
Anyway, I signed up with Site5 this morning and now everything is humming along. So far I am very pleased. Getting shell access is the only issue I have had so far and it approximately 2 minutes from the time I sent my email requesting shell access until I had it. It was was so fast that at first I assumed that it was an auto-responseShieldhost often took 4+ hours before the first response.. Even better Site5 supports RoR so if I ever get around to writing some cool rails app in my copious free time I can deploy them on barelyenough.org.
So far my only complaint is that the IMAP server does not support STARTTLS so I still have to get my mail insecurely. But apparently no one actually supports this functionality.