The goals of JamSpoon are a little ambitious, but like anything it must all begin somewhere. Being a kanban kind of guy, I want to start with something that will provide value immediately, that will go live and hopefully get real user feedback. As such, I have decided to place any UI work on the backburner (UIs are haaard), and instead start by evolving the design of what JamSpoons (the components that shuffles Jam to and from JamJars) should do.
To get this going, I am going to work from a real story that came up at my last job.
That is:
As an editor, I want to be able use the editing features of umbraco, but have the published content stored in ravendb, so that the devs can easily create my website in asp.net mvc.
In truth, the ravendb bit is a tad fabricated (noone cared where the content ended up, so long as it was accessible outside umbraco), but I thought it more useful to start with a very specific storage location, and generalise later. This story (well epic really – it will be broken down below) captures the starting point of my motivation for this whole project. Often we want to create websites ourselves, in whatever technology suits us, but we don’t want to have to create the UI for editing content on that site. That is, by rejecting the straightjacket limitations of a CMS in exchange for the freedom of using any technologies we like, we throw the baby out with the bathwater and lose all that content management infrastructure. This story is about having the umbraco CMS cake but being able to eat the asp.net mvc cake too.
So how will this mixed metaphor miracle materialise? What I am expecting to be able to do is hook into the publishing events within umbraco so that when content is published, the XML document umbraco uses is translated into the JSON documents RavenDB uses. This JSON is then sent off to RavenDB to store. The specifics of this functionality will emerge as I work through the following more specific stories (derived from the epic above):
1. As an editor, I want new documents published in Umbraco to be also stored in RavenDB
2. As an editor, I want documents unpublished from Umbraco to be removed from RavenDB
3. As an editor, I want new media (images, video etc) published from Umbraco to be also stored in RavenDB
4. As an editor, I want existing documents published in Umbraco to be updated in RavenDB
5. As an editor, I want existing media published in Umbraco to be updated in RavenDB
6. As an editor, I want the resulting documents in RavenDB to be useable in an Asp.Net MVC website
That covers the basic CRUD cases. But I am also interested in capturing the publishing lifecycle of content often found in CMSs (where version history is maintained, deletion is through unpublishing and content can be in a preview state). I expect the code will support both CRUD and publishing lifecycle models.
That is:
1. As an editor, I want the previous version of a document to be also retained in ravendb when a document is changed in umbraco
2. As an editor, I want to retain the previous versions of a document in ravendb when a document is unpublished in umbraco
3. As an editor, I want a distinct version of a document to be also stored in ravendb when a document is published for preview in umbraco
4. As an editor, I want a distinct version of a document to be also stored in ravendb when a document is saved, but not published in umbraco
(notice there is no mention of media here, as it is uncommon for versioned history of media resources to be maintained in CMSs).
Hopefully the usefulness of these stories shine out. That is, with these stories implemented, you could easily create a website in asp.net mvc, monorail, openrasta… anything, with content you are editing within umbraco. This independence of the resources from the tool used to manage them is the essence of the JamSpoon philosophy. Hopefully this small tool will demonstrate that philosophy and prove a few of the key concepts.
My next few posts will focus on the implementation of this. But as a teaser, here is how we could get from this starting point, to creating the full JamSpoon ecosystem.
1. Still within umbraco, create another module (similar to the ravendb one) that creates a copy of the content to the local file system
2. Just for umbraco still, refactor these two modules (ravendb and local file system) to sit behind a common interface, that captures the abstracted essence of what is being published out of umbraco
3. Refactor again, so that these modules sit behind a rest interface and are called via http (these will then be the first two JamSpoons – one for ravendb and one for local file system)
4. Now we are operating over http, implement the mongodb JamSpoon, which is running under Linux. At this point, we will have content published from umbraco being stored in mongodb. At this point we have now liberated the the resources not just from umbraco, but .net and windows.
5. Port the glue code that now lives in the umbraco module (that code that calls the JamSpoons’ rest api over http) to a completely different CMS, say Drupal! If this is possible, this means we can now publish drupal content to, for example ravendb, possibly without a single change to any of the existing JamSpoons…
6. Implement some more JamSpoons, for example AmazonS3, or even SVN…
7. Port the calling of these spoons to some more CMSs, say WordPress…
8. As patience permits port to various CMSs such as Joomla, Sitefinity, Expression Engine, Sharepoint(!), Orchard and so on
9. Again, as patience permits, implement a multitude of JamSpoons, such as Odata, Gdata, Memcached, Reddis, Couchdb – anything that allows schema-free storage of files like resources.
10. Possibly, even a JamSpoon that takes the Jam and rehydrates into objects and stores it in a schematic relational database using NHibernate. Sounds mad? Topgear does exactly this right now, so it’s possible….!
If this was all done, you could pick any CMS you wanted, and have it distribute the content to pretty much any storage location you liked, all via http over a uniform rest interface all the JamSpoons adhere to.
I won’t pretend these solutions wont have a few weaknesses, ie:
1. The documents will be duplicated in the CMSs and JamJars, with all the issues that involves (eg if someone edits the docs in ravendb, they will get overridden in the next umbraco publish)
2. The editor may get confused and frustrated that some things possible in the CMS they are using will have no effect (eg creating views in umbraco wont affect the asp.net website running on top of ravendb, for example).
These reasons are the motivations for ultimately creating the new JamSpoon UI, with all the Json Schema and workflow features I have mentioned before. But I think that needs to wait until I have experienced other CMSs, and seen what it is about them that should be incorporated in the JamSpoon UI (and, almost as importantly what shouldn’t be). The important point is that this UI will transparently be able to sit on top of any URL that implements the uniform JamSpoon rest interface. So whether you are working with couch or local files, the UI will work the same and look the same. The UI code (just like the umbraco/drupal/sharepoint code) will, in fact, have no clue what ultimately lurks behind that JamSpoon rest URL.
So with the creation of the JamSpoon UI, the CMSs could be left out of the equation all together. This UI would also provide a great multipurpose tool for viewing and administering the contents of the JamJars (raven, amazon s3, reddis, memcached etc) that could be much more convenient than what is provided natively by those products.
Having control of this UI opens up all sorts of other enticing possibilities, but I am definitely going to leave that for another time.
Thanks for reading so far, look out for more once I start coding.
Questions are welcome. I promise future posts will be a little easier on the eye (you know, headings and diagrams and things), once I return to civilisation….