Geeks With Blogs

News This is the *old* blog. The new one is at blog.sixeyed.com

Elton Stoneman
This is the *old* blog. The new one is at blog.sixeyed.com

Following on from Part 1 – Deploying Umbraco, we have a nice new installation of Umbraco, hosted in an Azure Website and using SQL Azure for storage.

In this post, we’re going to define some configuration settings for an application, capture the settings for one environment, and publish them as JSON – all without leaving Umbraco.

Define the Document Type

In Umbraco, content templates are called Document Types, and they’re set up in the Settings section from the left hand nav. We can host the config for multiple apps and many environments on one CMS instance, but the actual settings for each app will be different. So every app will have the available config settings defined in its own Document Type.

Let’s say the configurable values for my app look like this in JSON:

{ 
   "connectionStrings": 
   { 
       "redis": "connection;string;goes;here;", 
       "sqlServer": "and;for;sql;" 
   }, 
   "caching": 
   { 
       "lifespan": "PT10M", 
       "maximumSize": 300 
   }, 
   "appSettings": 
   { 
       "termsAndConditionsUrl": "http://static.xyz.com/tandcs.html" 
   } 
}

I have logical groups of settings, like connection strings and cache values, and some things which are generic app settings. I’ve used similar notation to the .NET configuration manager, so it will feel familiar for .NET consumers, but the app config API can be used by any framework that can talk HTTP+JSON.

To capture the template for my app, I’ll need a specific Document Type, but it’s likely that all the config documents will share some values, so I’ve started with an empty Document Type called Config Master which will be used like a base template for other document types:

image

Then I’ve created my specific config Document Type, called App 1 Config, which is based off Config Master:

image

The Document Type is where I’ll capture the structure and layout of my config settings.

Add Tabs for Logical Grouping

In the Tabs section, I can define the logical groupings I had in my JSON sample, so the UI can be presented with a similarly structured layout. Tabs are just names that group values in the Umbraco UI, so I can use whatever I want – I’ve saved the Document Type with tabs called Connection Strings, Caching and App Settings:

image

Add Properties for Config Settings

Now I have the layout for my document type, I can add the values I want to capture as properties of the Document Type. I’ll start with my Redis connection string, which I can add from the Generic Properties tab, and set it up as a string field which is shown in the Connection Strings tab:

image

The field name is what’s shown in the CMS when you edit an instance of the document, and Umbraco provides a field name for me by normalising my field title. “redis” isn’t very descriptive as a field name, so I’ve manually changed it to “redisConnectionString”. For each field I can specify a type – textstring in this case. Umbraco provides all the obvious types including a file upload, and you can easily define your own. I’ve also said this is a mandatory field, and I can add a regex expression for validation, and a friendly description to show.

For the other fields, it’s more of the same – and here’s the finished field definition:

image

Set Up the Content Hierarchy

With our empty Umbraco install, we have no root document, and no way to group config documents, which we’ll need. We want to be able to group app settings into environments, so ultimately we’ll be accessing the config from URLs like http://config.api.xyz.com/dev/app1, or http://config.api.xyz.com/test/app2.

To group config settings, we’ll create a Document Type called Environment – which will just be used like a folder to contain all the settings for one environment. In the Structure tab, I’ve set it up so that an Environment node can contain App 1Config nodes – as I add new document types for new applications, I’ll need to add them in here so they can live under an environment:

image

And for the entry point to the CMS, I’ve created a Home Document Type which can be used as the root node, and can only contain Environment documents:

image

Add Content

If that’s too many Document Types to make sense of, it should become clear now when I create the actual documents. In the Content section from the left-hand nav, I start with no content at all:

image

Then I add a Home document, which has no content fields, but acts as the root for the CMS:

image

And now I can add three environment nodes, Dev, Test and Prod which live under Home and will be the route for the config settings for the different environments for my apps. The name of the document forms part of the URL, so here we have three instances of the Environment document, with different names to provide me with groups of config for each environment:

image

And finally, I can add an App 1 Config document to capture the settings for dev:

image

I’ve named the document app1, so when we publish it we can access the content by browsing to …/dev/app1. The Content section of Umbraco is where you define the field values for the documents, so I can specify the actual Redis and SQL connection strings, and capture all the other settings in the other tabs. If I click Save and Publish  (publishing is a specific permission in Umbraco, other users may see “Send for Approval” instead), then the document is live – but if I browse to it I won’t see anything yet, because I haven’t defined the template that Umbraco will use to render the content.

Define the Template

Umbraco uses ASP.NET MVC, so you can define your document templates in C# Razor syntax. I have access to the usual ASP.NET MVC infrastructure, so I can declare that the response will be in JSON by setting the Response.ContentType in the template. You can also do content negotiation here, so you could return JSON if the incoming request asked for it, or default to HTML if not – which means you can provide a pretty preview for your config settings that you can view in the browser.

Keeping it simple, the template to render our App 1 Config document so it gives us the JSON we want, looks like this:

image

The document fields are available from the CurrentPage object, which is a dynamic so you can access the fields you defined without Umbraco having to build and compile a class to represent them. The UI lets you pick fields defined on the document, so you don’t have to remember them – but there’s no Intellisense.

I’m using JSON.NET, and building an anonymous object to give my API response the exact shape I want, and then write the serialized JSON as the response.

Check the JSON

Now when you browse to the …/dev/app1 endpoint you’ll get JSON out – I haven’t done any content negotiation in my sample template, so everyone gets JSON even without specifying an Accept header:

image

That’s It

We have a document type that captures the specific settings for an app, groups them into tabs for easy setting in the UI, and exposes the settings as a JSON response from an API call, which is actually rendered by the CMS using the template we built. It’s very simple, very quick and it lets us capture a definition for an application’s config and have different settings, using the same definition, for different environments.

In the next post, we’ll look at consuming that config API from C#, using dynamic objects in the same way that Umbraco does, so we keep the app flexible.

Posted on Friday, June 13, 2014 7:47 PM Umbraco , APIs | Back to top


Comments on this post: Using CMS for App Configuration - Part 2, Publish Your Config

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Elton Stoneman | Powered by: GeeksWithBlogs.net