Monthly Archives: February 2013

Review of “Service Design Patterns” by Robert Daigneau

I’ve recently been reading through Martin Fowler’s Signature Series of books, published through Addison-Wesley. I like curated collections like these because they save me the work of assembling high-level curricula on my own, and it sounds like Fowler actually read these books before recommending them, which is a definite plus.

I just finished tackling the first book in the series, “Service Design Patterns,” by Robert Daigneau. (They should have prepended the word ‘Web’ to the title, in my opinion, as ‘service’ is a very general term.)

I enjoyed the book, but the signal-to-noise ratio was a bit low for my taste. I found the most useful contribution to be the classification of web service endpoint design “styles” into three major types:

RPC API: A remote interface that is designed as a procedure which takes multiple typed arguments. (e.g. GetInvoiceList(customerID, startDate, endDate, phaseOfTheMoon)).

This one is easy for newbies to understand, and amenable to implementation via code generation. Tends to produce very flat, grab-baggy APIs and service contracts are easily broken if you have to e.g. change the parameter list to a call.

Message API: Similar to RPC API, except that each endpoint receives a single typed parameter that encapsulates all of the parameters to the call in a “message” or “document”. This gives you a bit more flexibility in how the service contract evolves, because the message classes themselves can be versioned and routed to the correct handler by the endpoint based on this version. (Google’s protocol buffers are used as the primary example of this.)

For example:

service Invoice(InvoiceRequest)

message InvoiceRequest {
	version = 1.0
	startDate  = ...

Resource API: This is what most newbies to the field will encounter as their first example of a web service API these days, which is potentially unfortunate because it is the most complex. The resources (nouns) of your system are exposed via dedicated urls, and you retrieve or manipulate these nouns via verbs that are represented by HTTP methods like GET, PUT, DELETE, etc.

I found this classification (and the short history in chapter 1 that motivates it) to be very clarifying, and I lived through the evolutionary process that created each of these styles. If you are early in your software engineering career and a RESTful API is the first example you ever see of a web service API, I don’t think it will be obvious to you why the rest of the world decided this was a good engineering practice (pun intended). The historical discussion and subsequent classification of web service style APIs gives one a clear list of general possibilities to consider when consuming or creating a web service API, and is thus good reading in my opinion.

The rest of the book is devoted to enumerating specific design patterns that can be used in the implementation of each service API “style”, and then shows how to implement it in a common Java or .NET framework.

The thing is, the implementation of these patterns is really quite simple. I think it would have been much better to discuss a concrete example of a requirement that would motivate the use of the pattern instead, since that discussion would be much more resistant to change than boilerplate code.

Slightly “advanced” topics like service registration and discovery are discussed here as well, but I don’t think I’ve ever met anyone who was confused (or thrilled) by the idea of a service registry.

My conclusion: I’m definitely glad I read the first two chapters. The rest of it was educational in parts but had a very low signal-to-noise ratio. If you see a copy on someone’s shelf, do yourself a favor and read the first ~50 pages or so — or even better, recommend it to a new CS grad or junior dev.