Jason Deacon Team : Web Development Tags : Technology Web Development Programming Umbraco MVC Featured

Decoupling Umbraco from your front-end website

Jason Deacon Team : Web Development Tags : Technology Web Development Programming Umbraco MVC Featured

Recently we started work on a project which required a databaseless front-end website. Faced with this proposition we decided to approach it using a back-end instance of Umbraco 7 which was completely decoupled from the front-end. This means that the front-end website (in this case, an ASP.NET MVC 5 site) will not connect to a traditional RDBMS to serve content to its users.

The below diagram illustrates a very high-level overview of how the database, Umbraco and the front-end website are related.

Decoupling Umbraco

Our approach leverages a file called "Umbraco.config" which is really just a XML file which Umbraco publishes all its public content to whenever a node is published in the interface. This XML structure mirrors the document types and properties of the site structure populated in Umbraco and therefore offers the perfect snapshot of the content the site can serve, without having to query a database for it.

The below diagram shows quite clearly that there are two distinct sites, one which operates Umbraco off a regular database, and one which operates a MVC 5 site off the generated Umbraco XML.

The connecting line in the above diagram (which says "Offline Process" if you can't read it) denotes any kind of manual or automatic process to make the Umbraco.Config file accessible by the public website. These processes could be as simple as copying the file from one server to another using remote desktop (which is not recommended) or more feasibly, by using a task (either scheduled or triggered by changes to the file) to copy the file to the intended destination. But however it is approached, it's not the responsibility of the Umbraco site nor the public website. More control = more flexibility.

But what about media?

There is one caveat however, which is media. When you use the standard media picker property types in Umbraco you are actually saving just the media id to the resulting Umbraco.config file. Umbraco would normally then perform a database query when you request media information on the front end site but since we do not have access to the database we cannot perform these media queries. What to do?

The solution is to hook in to Umbraco's MediaService events by using a custom ApplicationEventHandler and generate our own XML file of all the currently published media. It sounds way more complex than it is:

    
public class CustomEventHandler : ApplicationEventHandler
    {
        protected override void ApplicationInitialized(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext)
        {
            base.ApplicationInitialized(umbracoApplication, applicationContext);

            // Any time media is changed we need to ensure that the media.config is up to date for front-end sync purposes
            MediaService.Saved += MediaServiceSaved;
            MediaService.Deleted += MediaServiceDeleted;
            MediaService.Created += MediaServiceCreated;
            MediaService.Trashed += MediaServiceTrashed;
        }
		
		....

Then in each of the event handlers, simply call a method such as:

	
private void RefreshMediaData(IMediaService sender)
	{
		var images = sender.GetMediaOfMediaType(UmbracoImageContentTypeId);

		var media = new List();

		foreach (var img in images)
		{
			MediaImage newImg = new MediaImage();

			BindMediaTo(img, newImg);

			media.Add(newImg);
		}

		SerialiseMediaList("~/App_Data/media.config", media);
	}

And then we have a resulting XML with all the data we need to show the media on the public site. See, easy!

On the front end

In the front-end it's just a matter of loading the relevant XML files (umbraco.config and media.config) and providing a way to query them easily and efficiently. In this case I'm using LINQ to XML to query the Umbraco.config file since the structure and properties can change dramatically over time.

As for the media, I'm simply loading the file and deserialising the media items into an in-memory dictionary which is accessed via a repository like normal.

If you're still reading this then you're probably the type of person to already twig to a very important benefit of accessing data this way.. performance!

Performance

..in fact so fast that we can perform ~280,000 queries per second.

Performance of querying via LINQ to XML, including mapping attributes/elements back to our custom model classes is in fact so fast that we can perform roughly 280,000 queries per second. This is far beyond and traditional RDBMS approach and means that we can display some very data-intensive pages with little to no problems in terms of page response times.

Conclusion

So next time you need to decouple Umbraco from your front end, consider the approach proposed here to see if it meets your requirements. It's very straight forward and extremely performant!