Seamless Audit Trails in RavenDB

September 07, 2012

Since the basic product sold by software consultancies is consultant-time, you would expect there to be pressure (gentle or not), to put in as many billable hours as physically possible, to the detrement of quality. Fortunately, Headspring takes the long view: excess hours this week may make this week's revenue numbers jump, but sustainability matters more for all involved. I first experienced this policy as a reliable 40 hour work week, but it doesn't stop there. When you take the long view, you respect the need to put some unbillable time towards improving your own skills. This week, I got to take advantage of that flexibility by attending Headspring's own RavenDB Boot Camp, taught by Alonso Robles.

When new software tools come around, they almost always claim to "Just Work". Even ravendb.net makes this claim. Real software problems tend to involve lots of competing concerns, so we should always take such claims with a grain of salt in addition to an open mind. During the Boot Camp, I got to see a perfect example of where this "It Just Works" claim comes from.

RavenDB supports plugins called bundles. Bundles are installed by dropping a DLL into the Plugins folder beside the server exe. One of the bundles demonstrated during the Boot Camp was for Versioning writes and deletions. This bundle has quite-reasonable default behavior, so installation is just a matter of dropping the DLL into the Plugins folder.

We students didn't know exactly how this audit trail would present itself to us. How would we find the trail, inspect its contents, or revert to some older state? To find out, we dropped the bundle in its new home and started creating and updating documents through Raven's admin tool. There was a collective, audible "AHA!" moment among all the students. We were updating a document whose ID was "products/4", and right beside it in the admin tool's list of related documents, we started to see "products/4/revisions/1", "products/4/revisions/2", "products/4/revisions/3"... A full copy of the document was being stored upon each change.

The unit of storage of your primary data in Raven is Just Some Document, so why not also store the audit trail as Just Some More Documents? A completely-understandable naming convention and a little metadata is all we need to work with. Of course, the bundle also lets you fetch the revision history from your own application, and reverting to an older state would simply be a matter of fetching the revision you want and saving it again. The beauty here lies in how the bundle leverages Raven's world view. Implementing an audit trail didn't require some fundamental change to the way Raven works, and we didn't have to roll our own audit trail by increasing complexity in our client application. Instead, it just used the existing Raven infrastructure.

Earlier, I warned that "It Just Works" claims need to stand up to competing concerns. By allowing for this kind of low-impact behavior change, adding a Versioning feature to our application doesn't have to compete with the rest of our application's concerns. We didn't have to make some painful, sweeping change everywhere our client touched the database, and the opportunity to add a history viewer to the application itself was readily available.

One is an extremely small sample size, so I'll need to experience more of these "AHA!" moments, but this does suggest that the deliberately-simple mental model promoted by Raven leaves the door open for us to seamlessly introduce features into our projects.