This evening at XPSTL, Michael Feathers (blog) (book) was in from out of town (and from around the world) and gave a talk on API design. He’s been thinking a lot about API design recently, driven by issues that come up with working with legacy code, which talks to lots of APIs, to cajole it in to a more testable state. I think there is a lot to say (maybe a book’s worth?), and a lot of what has been said elsewhere turns out to yield APIs that are unduly difficult to build testable code with.
What we end up doing here, and a thing that Michael says is not at all unusual, is to “wrap” most APIs with some application code, to enable:
- a simplified way to call the external component / API, more suited to our needs
- easy testing, as we can design our wrapper to make it trivial to substitute a test/mock implementation
- a buffer from future changes in the external component / API
- easier migration to alternate implementation of the same underlying services
Our wrappers tend to be “flatter” and simpler than the underlying APIs we wrap. For example, most of our use of Hibernate is behind a class we call DataSession, which represents the connection/session, transactions (it encodes our policies on how to use transactions) and many named methods for query operations (thus we avoid scattering HQL or SQL around the project).
Also, we had a big crowd at XPSTL – the room was packed.