Practical REST on Rails 2 Projects
by Ben Scofield.
Apress, Berkeley 2008.
284 pages.
[Full disclosure: I have received a copy of the book in exchange for this review.]
The book, targeted at intermediate and advanced Rails users, starts with a chapter “Why REST?” that tries to explain how REST helps interconnect applications and reflects the structure of the web. As examples for such connectivity a few mashups are presented. The author states that APIs can make web applications much more useful and interesting, but costly to develop. He contrasts REST with XML-RPC and SOAP. Finally, the basics of REST are outlined: It is a client/server architecture based on stateless requests that describe and transform resource representations. The author argues that REST makes it easier to develop clients and servers and extend these applications in the future, last but not the least because REST is implemented well in Rails 2.
After demonstrating the use of (deprecated) ActiveWebService, the author shows how these ideas are expressed nowadays in Rails 2, outlining the history of simply_restful. He continues by explaining the new styles of URI routing that also dispatch on the HTTP method like map.resources/map.resource/nesting and map.namespace. The author also addresses Rails’ support for multiple output formats and new helpers related to routing. Scaffolding is discussed and will be used in the book. At last, there is a mention of ActiveResource to use RESTful Rails applications together.
The third chapter develops the main application of the book dubbed MovieList. It is used throughout the rest of the book. MovieList, a site that informs about movies and their releases, lets users express their interests and displays when new movies with the same actors are released. The code is not developed test-first, but the downloadable code contains a test suite. Occasionally the code is pretty weird, for example it defines setters that are merely called for their side-effects using #update_attributes. In some places, explicit iteration over ActiveRecords would have been solved better by doing it in the database. Also, the generated HTML is partly unsemantic and hard to scrape (which is not that bad if the data can be reached by the API, you may argue). The author explicitly defines notifications and interests for the movies to belong to the logged-in singleton user (they reside at /user/interests, not /users/:id/interests), supposedly so one cannot see other people’s interests. In later chapters, he decides however to at least revert this for notifications—it would have been better to properly design it in first place, as it actually is a nice feature and more RESTful anyway (can you speak of “current users” in a stateless request, really?) and show how to protect the page for users that don’t want to allow it to be seen. The author mentions at the end of the chapter that a “great deal of planning, testing and other work has gone undescribed”; wouldn’t it have been useful to have these parts in the book as well? The actual architectural concerns of REST applications are not really mentioned in the book.
The next four chapters deal with accessing the MovieList applications from other technology. Chapter 4 uses JavaScript to provide a widget users can embed on their homepage and shows how to do full-fledged access to the application using AJAX after extending it to support JSON. Chapter 5 shows how to access the site using the PHP framework Squidoo. During this, a feature is added to allow users to display the movie releases within a time frame. This is the code used to parse the relative time, and I’m not kidding:
raw_time = params[:time] || '1 month'
time = eval("#{raw_time.sub(/ /, '.')}.from_now")
How this gaping remote code injection hole passed any kind of technical review is a miracle to me. Ironically, the next section is called “Injection Flaws”, and addresses SQL injection and so-called “HTML injection”, which actually is passing anything you want as parameters. The author then decides to “fix” it by checking the time parameter in the PHP script calling the Rails application. Duh.
Chapter 6 builds an client for the iPhone, optimized to its interface constraints: a small screen, popup keyboard and lower bandwidth. It uses the commonly used approach of defining a new Rails format that is triggered by a special subdomain or by user agent sniffing. The chapter shows how to use iUI to make the interface look native, too.
Chapter 7 shows how to embed the application to Facebook either by using iframes or the FBML. I have no idea how the contents of this chapter are related to REST, especially since the FBML approach actually calls everything using POST.
Chapter 8 is called “Dealing with success” and is about making the application faster and more robust. Apart from the classic caching approaches (which work very well in REST due to the idempotency of GET, but see below) and foreshadows of denormalization, it contains a few general hints on Rails and database performance. It also addresses throttling access to the API by using API keys and setting up auditing to monitor the site.
Finally, Chapter 9 tries to place “Rails in the enterprise” and explains the chances, but also the problems of REST and Rails in the enterprise. It contains a small example of how to create a RESTful interface for a SOAP backend.
Conclusion: Generally, I found the book lacking. Instead of shifting focus to the design and architecture of real-world REST applications and showing up the patterns that can be used to help development, the book shows how to combine a simple CRUD application with half a dozen of buzzword loaded Web 2.0 stuff. The semantics of REST are only half-heartedly addressed (a third of page 13 discusses what the HTTP methods mean), the idempotency of GET merely assumed (it’s actually in a parenthesized half-sentence on page 72), and the actual means of applying REST (proper status codes, correct/multiple content types) are not made explicit. Instead of wasting over 15 pages on screenshots unrelated(!) to the application and another 2 pages on showing a WSDL that is very much useless, the reader would have had more benefit from a table of HTTP status codes and content types. Also, writing a REST client in Ruby is not addressed by means other than (the limited, non-general) ActiveResource.
I think this sounded too negative, please bear with me: The book is okay. It’s well written, and if you like a whirlwind tour of Web 2.0 things one can do it’s a good read. It’s just not really about REST, or at least not what I’d expect of a book about REST.Rating: 3.5 of 5 points.
NP: Dandi Wind—Hostages