Houston TechFest 2013 is around the corner. This is a free to the public (except for parking) event with a number of great presentations and exhibits taking place at the Reliant Center on September 28.
I will be giving my Up and Running with RavenDB presentation for the third time. Although, I have revamped it by incorporating the feedback I received from earlier events.
Last night, I presented a deep dive session on RavenDB indexes at the Austin .NET User Group. It was a blast as I got to see some familiar faces and was able to engage in some exciting RavenDB discussions.
Here are the slides from the presentation:
There are a few upcoming RavenDB events that I am very excited to be a part of. Check the links for more information:
Following my recent post about getting started with RavenDB, I decided to work on a small shopping cart demo application based on the sample depot application that is written in part 2 of Agile Web Development with Rails when I started running into some trouble with the RavenDB auto generated document identifiers and the MVC routes. Like any other programmer, I quickly performed a Google search to see what others had done. The search led me to a few Stack Overflow well voted answers all leading me to a blog post on this topic. Problem solved right? Not exactly. Two solutions were proposed. But before getting into those, I want to describe the problem a little more.
The Problem Described
Take a look at the ASP.NET MVC 3 default route found in the Global.asax.cs file:
This default route will basically allow you access to a resource using the basic URL convention that may look something this: http://localhost/products/edit/1 . However, the default RavenDB auto generated document identifier for the product document ends up looking something like this: products/1. (More information about the RavenDB document identifiers one of the documentation pages. ) So the URL to access that product resource for editing would really have to look like this: http://localhost/products/edit/products/1. Well that doesn’t work for two reasons:
The default route will not be matched so the URL will not be routed the correct controller action.
The URL is not SEO friendly.
Typically, this can be solved by using a custom route that access this resource by a natural key where the URL would probably end up looking like this: http://localhost/products/product-name/edit. This makes the URL SEO friendly, easy to read, and easy to route. However, there are some situations where the document identifier makes sense and I will continue this post on the assumption that this is the case.
The blog post mentioned above presents two solutions:
Solution 1 – Change the identity parts separator convention for the RavenDB document store.
Solution 2 – Modify the ASP.NET default route
Issues with Solution 1
Let’s look at the first solution. The suggestion is to change the identity separator convention from a slash (/) to a dash (-). The convention is really easy to change during the initialization of the document store object.
This makes RavenDB generate document identifiers that now look like: products-1. Now we can generate a URL that will match the default route and may look like: http://localhost/products/edit/products-1. I still find some issues this this. Namely, the URL is still not really SEO friendly and not really human readable. I don’t like the idea of exposing an identifier that was forced on me by RavenDB since it essentially has coupled my URL to the RavenDB identifier convention. It just doesn’t feel right.
Issues with Solution 2
This solution suggests the change of the default route to something like:
This will allow route to match a URL that looked like the first one: http://localhost/products/edit/products/1. I don’t like this either. While it does allow the default route to match and do its job. The URL is just ugly. It also clobbers the id making the route also match something like this: http://localhost/products/edit/products/more-junk/1. Obviously this is not SEO friendly or human readable. Again, it just doesn’t feel right.
After some digging and learning about more about the document identity field, identity type converters, custom identifiers with the document key generator convention, I realized there was a pretty simple alternative to the two options above. But to see it and to understand the simplicity, you have to look at the source of the problem.
The reason that MVC routes are choking on the preconfigured RavenDB document identity convention is because our models included a string based identity property. I realized I had done this on purpose to ease the mapping of the RavenDB document identifier and my object identifier. Take a look at my product object definition:
The shopping cart identifier is a string. Why would it be a string? It could have been an integer or a Guid or something else. It could have even been a natural key of some sort. Or even a compound key. It doesn’t have to be a string. Taking another look at the IDocumentSession interface we can see we have four load methods available.
After thinking about the difference between the method that accepts a string identifier and the one that accepts a value type identifier, I realized that all I had to do was change my identifier type from a string to a value type and I’m done. No fancy mapping or parsing the document identifier from RavenDB to the web browser and back. No changes to the default MVC route. No changes to the default identity separator convention. It just worked. My URLs are SEO friendly and more readable.
All I had to do was change the object identifier type.
That was easy.
Of course this doesn’t solve everything. What if I really do need a string based identifier? This will probably require tweaking the behavior of the RavenDB client. I also don’t have an answer for compound keys and other natural keys which may not be a value type. Some of these may require more thought from both the RavenDB side and the MVC side of my project. But that is another problem to think about some other time.
I have recently stumbled on a couple posts from Martin Fowler related to a NoSQL Distilled joint book authoring effort. The book announcement excites me as I am looking forward to reading it for a several reasons. Primarily because I have been like a overindulged my inner geek this past year – playing and getting a taste of what I call modern persistence systems. Learning and thinking about Brewer’s CAP theorem and its implications while setting up and trying a few things out with Cassandra and Hbase has been very fun to say the least. However, one thing has bothered me… what do we call this new era of persistence methods?
Today, I came across another post from Fowler where he discussed the term “NoSQL“, what it means in today’s persistence movements, and how he will be using it in his new book. This made me think about all the terms I have heard recently other than NoSQL. Here are a few others:
Polyglot Persistence – Another term I learned from reading Flower’s Bliki at least six months ago or more.
Big Data – Which is typically used to describe the problem of large data sets which cannot typically be accommodated by today’s traditional relational database systems due to cost, performance, and/or other operational concerns.
Another interesting discussion point, is the interest in other data store models some of which academic circles have previously explored. The recent interest, in my opinion is probably due to the changes in computers and networks since the time when the RDBMS became the preferred standard for data persistence many years ago. Ayende Rahien talks about this on a blog post. Some of different store models available (or in development) current NoSQL systems include:
There are many more discussions taking place in today challenging how we think about persistence. Even traditional physical persistence mechanism is in question. A few years ago the idea of using anything other than a hard disk or a SAN for persistent storage would have been absurd. However, a physically distributed in-memory non-relational database is a viable option (most likely this option will be geographically distributed). Other topics of discussion include:
Truth is I don’t know what to call this current persistence movement. To me it seems obvious that terms like “NoSQL”, “Big data”, and even “Polyglot Persistence” are insufficient. We are definitely now in a different era where a new persistence paradigm has begun. The relational database management systems no longer the only option. While those systems continue to have their place in today’s computing era, their market share is starting to shrink. Relational databases may even evolve to take advantage of the advancements made in this area.
The development, discussion, and research of new persistence solutions is happening now! Challenges issued to older traditional persistence systems are inspiring the revitalization, evolution, and enhancement of the existing software. Some of the old and new will survive, a few will thrive, and many will die. These are exciting times!