Jamis Buck’s recent article extoling the virtues of UI-centric design makes the point that by designing the signature screens of your application, you can uncover its domain more reliably than you ever could from a marathon UML whiteboarding session. But as anyone who’s ever jammed on a whiteboard with boxes and arrows knows, Domain Driven Design can be hella fun, and it can certainly uncover more modeling than a few designer screenshots.
At Grabb.it we have three or four core user screens: the main player page, which we’ve been refining for months; the pages corresponding to individual tracks; and the signup and login workflow. For these screens, a UI centric approach has paid off.
But our domain model is much richer and deeper than our users ever care to know. Because we want to support features like allowing users to supply their own music metadata – custom names for songs, etc – as well as support a recommendation engine, interface with MusicBrainz and other APIs, and provide XPSF playlists of everything, we’ve got rad awesome extreme crazy fractal constellations of UML dancing in our heads. Let’s zoom in on a parser:
All that complexity is very hard to manage outside the context of RESTful conventions. I know because I’ve tried it. We first prototyped Grabb.it in late 2005, when Scriptaculous was hot off the presses and has_and_belongs_to_many was the law of the land. If you visit the site now, you will find code that is far from RESTful. push_with_attributes abounds.
In the current rewrite, we are doing things right, as far as I’m concerned. And it turns out to be the opposite of what Jamis suggests. Every time I need a new database table, I script/generate rspec_resource which scaffolds out models, controllers, and specs. As I’ve been writing the models and glue code that supports our user facing pages, I’ve completely ignored the generated controllers. I highly recommend working this way.
Last night we made a chart, really a grid, which listed all the controllers down the side, and the actions “index (and scopes), show, new, create, edit, update, destroy” across the top. We went controller by controller, even through obscure join models, and discussed what kind of access restrictions each controller will have. Most of them turn out to be admin-only, forming our “shadow application” which we can use to diagnose and correct the running system. Sessions#index, anyone?
We also discussed what kind of information would be presented there. This challenged our assumptions. Surely the show page for an Artist should present all tracks by that artist? Not so much when you realize that what you’re really talking about is the Tracks#index, scoped to the Artist. The more we thought about what an Artists#show could bring, beyond a way to play their songs, the more compelling that page became. It ended up in the rarefied few circled in bright blue, the color reserved for signature screens. We’ll get UI-centric for this new page we discovered through RESTful application design.
Try this next time you are modeling a new application. Generate scaffolds every time. Either replace them with a signature page, or ignore them. Sometime after you have a handle on your models, reevaluate the controllers. Your app might surprise you, Grabb.it did.
Be the first to comment on RESTful Application Design (with Scaffolds!)