It's been several weeks since I went to the Alabama Code Camp that was held here in Huntsville, but there's been one concept that was mentioned in a session that I think has noticeably changed my development habits. It's something I heard mentioned in a talk by Shawn Wildermuth about Microsoft's Astoria project: queryable endpoints.
I think the core idea is that, when structuring a database's schema or when writing data access code, it helps to keep a data model simple and avoid baking inappropriate aspects into it such as aggregate columns or a default sort order. One's goal should instead be to create an understandable, clean model that allows its consumers to transform data themselves (via filtering, sorting, summing columns together, etc).
In the talk, Shawn discussed how the Microsoft data access team is trying to build one solution for this with Astoria. The stated goal of Astoria is "to facilitate the creation of flexible data services that are naturally integrated with the web". In its simplest form, it basically allows you to expose data in a RESTful manner via URLs like this:
which returns a list of Customer entities, or in a more specific way like:
http://server/data.svc/Customers(’ALFKI’)/Orders?$filter=Active eq true&$orderby=OrderDate
The caller can request that entities be returned in JSON or ATOM format, and the format can be chosen with a flag in the HTTP request header. It seems Astoria provides the mechanism for such communication, but the back end (how you talk with data sources) can be constructed in a variety of ways using .NET (talking to XML files, various databases using ODBC, even remote web services).
While Astoria sounds very exciting, and I hope I get to play with it sometime, just keeping the concept of queryable endpoints conscious has proven beneficial to me on my current project in the past couple weeks. After the code camp talk, I looked back and saw where me and my team had violated this idea in a few particular ways: we had created many inflexible, overly-specific stored procedures in the database such as "GetUsersByLastLoginTimeDesc" and also ones that retrieved records given a filter which ended up being raw SQL (which is certainly not a very maintable practice).
While these may be very glaring examples, sometimes the decisions can be a little more subtle and easier to slip through. This week as I was creating a new data structure as part of the data access layer component of our application, I found myself throwing in an aggregate field which summed together several others. The data structure was to be used in forming a data grid for a specific page and this would have made things easier for that particular page, but I saw where it could easily be useful elsewhere and wanted to of course make it generic. It was a little more work to therefore customize the data grid on my page to create an aggregate column, but looking back I can easily see where that was the proper place to put that piece of logic.
A lot of this is probably common sense or just a feel for software engineering that I haven't quite development yet, but I think keeping this idea in mind has helped me to put code in the right place.