A few weeks ago, I came across Sinatra, a minimalist Ruby web framework, much leaner, meaner and simpler than Rails — while it’s probably not a good fit for traditional database-backed web applications, it seemed like an ideal framework for Deltacloud Core.
Deltacloud Core is a cross-cloud API providing abstraction and compatibility across multiple clouds. There are quite a few such API’s out there; what makes Deltacloud unique is that it is not a client-side library tied to a specific language. Instead, it is a RESTful web service, initially written in Rails by Bob McWhirter.
While Rails was a good initial framework for Detlacloud Core, and is the default Ruby web framework for a reason, there’s a few things that make it overkill for a simple webservice:
ActiveRecord
Of course, the biggest draw of Sinatra is that it concentrates all the
controller code in one place (currently ~ 300 lines in server.rb
), which
makes it much easier to understand how the whole application is put
together. More generally, using Sinatra makes it possible to concentrate
code in fewer files, increasing readability.
Out of the box, Sinatra fell short of our needs in two areas: RESTful request validation and responding with a variety of content types.
Michal and I took care of request validation with a small custom DSL for describing RESTful operations, cleverly called Rabbit. That DSL lets us talk about collections and operations on collections, and generates validation logic and online documentation on-the-fly. You can browse an instance of Deltacloud Core and immediately see what operations are available, and what parameters a specific operation like create instance accepts. (Why and how that is important is a topic for another blog post)
Deltacloud Core can be used in two ways: you can either point your web
browser at it and browse a variety of information about your objects in a
specific cloud, or make RESTful requests that return XML responses. That
dual nature makes it necessary to respond to some requests with HTML, and
to others with XML. Sinatra doesn’t have a mechanism that’s as convenient
as Rails’ respond_to
for this, though there’s a nice
extension that does
exactly that, so that we could write listing of a collection, any
collection, (model
in the code below), simply as
singular = model.to_s.singularize.to_sym
@elements = driver.send(model.to_sym, credentials, filter)
instance_variable_set(:"@#{model}", @elements)
respond_to do |format|
format.xml { return convert_to_xml(singular, @elements) }
format.html { haml :"#{model}/index" }
end
The Sinatra respond_to
extension actually didn’t do content negotiation
based on the Accept
header; we added that based on a couple of existing
Rack extensions. And discovered in the process that Chrome’s Accept
header is
utterly insane.
All in all, the move to Sinatra worked out very well; existing functionality was easy to preserve, and we added validation and self-documentation to Deltacloud Core, both in human-readable format and as (experimental) XML. Next up: more features for the API.
Watzmann.Blog by David Lutterkort is licensed under a Creative Commons Attribution-Share Alike 3.0 United States License.
Generated with Jekyll