This is probably going to be the final part.
Last time I stopped just getting ready to talk about designing a JSON based RESTful API.
My initial design had no consideration for an administration component. Every action had a block that looks, at the bare minimum, like this:
RUBY:
-
respond_to do |format|
-
format.js
-
end
I cared about JSON more than HTML or XML (I included XML where it was easy enough on the first pass simply because .to_xml is just as easy as .to_json). Another developer's concern was an HTML-based administration interface for the end users to use. My JSON part was going to be used by "meat" of the project to interact with the database.
At the start of the project I had about two dozen or so models to represent the application. This is all going to sound the same:
ruby script/generate resource -c Person
ruby script/generate resource -c Avatar
And so forth.
Add the basic four (really five) CRUD operations to each controller:
RUBY:
-
def index
-
end
-
def show
-
end
-
def create
-
end
-
def update
-
end
-
def destroy
-
end
(Don't forget helpers!
RUBY:
-
before_filter :get_thing, :only => [ :show, :update, :destroy ]
-
protected
-
def get_thing
-
@thing = Thing.find params[:id]
-
end
)
And then fill in the blanks. Edit config/routes.rb to do resource nesting so editing the first Person's Avatar(s) is baked in to the URL and the caller doesn't have to worry about polluting the URL with parameters that aren't needed.
The tests become simple, too. There isn't much complexity to most resources, thankfully, it's always testing five basic actions.
My coworker that was doing the HTML only had to add a format.html in the respond_to block as well as two new actions (new and edit) to handle peripheral HTML forms that my JSON-using clients would never use. Handy, that.
By using CRUD it meant that REST could be used in Rails automatically. The actions just worked. Resource nesting just worked. I got to spend time thinking about cool stuff, like the application, and not how to make "it" work, kind of like why I liked Rails in the first place! No glue code.
CRUD/REST makes me a happy coder. Using CRUD means, for example, that buying a Product in a E-Commerce store it isn't an operation on a Product per se, but rather it is the creation of a CartEntry in a Person's ShoppingCart (POST /people/1/shopping_cart/cart_entries) and to check out it's just a creation of an action on the ShoppingCartController called, for example, checkout attached to the DELETE HTTP verb. It's debatable whether or not DELETE should semantically mean "Okay, now let me purchase everything" but that's another post.
In the checkout method there's then a concern of what do I do with all these CartEntries? What about a model called a ShippingQueue that the people in the shipping department at the store can use (with RESTful interfaces!) that has some state attached to it (ShippingStatus < AR::Base and then Shipped < ShippingStatus; Received < ShippingStatus, etc). Models are cool.
That's the end. CRUD helps me and that's all that matters in the end.