Geeks With Blogs
Liam McLennan

I read somewhere that Kent Beck likes to apply a strategy of taking a technique that works and exaggerating it, to see if the results are likewise exaggerated. He found that specifying the behaviour of components prior to implementation, and in small increments, produced good design, so he exaggerated it and now we have TDD. He found that strong engineering practices, rich communication and delayed decision making was a good way to run projects, so he exaggerated it and now we have Extreme Programming.

In homage to Kent Beck and his work I decided to apply his technique to web frameworks, taking the things that I like and exaggerating them. Here are some of the things that I value in a web framework:

  • a rich language
  • simplicity
  • minimalism
  • expressiveness
  • opinionatedness

Using the above guidelines I sketched out an idea for a server-side framework for CoffeeScript. It is heavily inspired by Sinatra, with a few minor tweaks and coverted to CoffeeScript. Here is what a controller might look like:

# The first parameter is the route. Like sinatra, there is no route abstraction.
# The second parameter is a method to execute when the route is matched.
# Enforced one-model-in. No need for params[]

get '/', (input_model) ->	
	"Hello World"
# Views are found based on the name of the model passed to the view method.
# ? here is the CoffeeScript existential operator.

get 'address/:slug', (address_request) ->
	if address_request?
		@address = address_finder.find_by_slug address_request.slug			
		view @address	
# View model objects are automatically given bind_to() and update() 
# methods for binding to and from domain objects.

post 'address/create', (address_model) ->
	@address: address_model.update new Address()
	# do something with @address
	@address_list = address_finder.all()
	view @address_list

As promised the implementation described has some strong opinions: one-model-in, binding methods on view models and no route abstraction.


One-model-in is a rule that no action may have more than one parameter. All request values (querystring, form, route) are mapped onto the input view model.

Binding Methods on View Models

The input view model objects are automatically given bind_to() and update() methods. By extending the base view model class developers can create more sophisticated view models.


Bind to copies the attributes of the input domain object to the view model object.


Update copies the attributes of the view model object to the domain model object.

No Route Abstraction

Most MVC web frameworks have an abstraction for routes, meaning that a url is mapped to a route and the route is mapped to a controller action.

Url <—> Route <—> Action <—>

Sinatra simplifies by omitting the route abstraction, and I have too. The advantage is simplicity, the disadvantage is that refactoring an application’s URL scheme might be more difficult.

Posted on Sunday, June 27, 2010 6:20 PM | Back to top

Copyright © Liam McLennan | Powered by: