Umbraco Rest Api

Here at SteadyGo we are big fans of Umbraco for many reasons, one of the main ones is the community surrounding Umbraco development. If a developer creates a package that becomes very popular, the guys at Umbraco HQ often integrate that functionality into the CMS or help develop and maintain it.

One of the handiest we have come across so far is the Umbraco REST API package, installed as a DLL in an Umbraco project it allows you (with some minimal configuration) to expose several REST API endpoints which allow CRUD (Create, read, update, delete) of Members, Content, Relations and Media.

While there are many possible uses for this, probably the most useful to us is to use Umbraco to manage content and users consistently across several platforms without having to build some kind of API ourselves.

For example if you may have an Android app, an iOS app and a website which all need to share content and users. You could build your own architecture to manage this or use a 3rd party service both of which are viable options but do have time and cost implications. With the Umbraco REST API package you can get a central content management system up and running in no time at all to allow none technical users to easily update content across all platforms.

So how do I use it?

That all sounds great but how do I get my hands on this HTTP verby goodness? I hear you ask! It’s simple enough but there are some important steps that need to be followed. I found the best article to follow was this one by 24Days.in (I suggest you read it now!) so I won’t repeat what’s said here as they do a good job of explaining the set up.

They don’t however go into much depth of how to actually interact with the API and what goes where. The best way I found to see how it all works was to actually download the source code and add it as a project to the solution then step through with your favourite debugger.

The handy thing about the API using the HAL specification, as explained in the previous article, is you can navigate the API by the content returned from the previous call.

Authenticating

To authenticate you need to use a back office user login as your credentials to obtain an OAuth token to send with future requests. The following can be used to obtain the token, I’ve in lined some bits for clarity (one thing to watch out for, the umbraco site needs to be running https in order for you to use the REST API stuff):

public AuthTokenModel GetAuthToken(string username, string password) { HttpClient client = new HttpClient(); client.BaseAddress = "https://www.mysite.com/umbraco/oauth/token"; HttpResponseMessage response = client.PostAsync("Token", new StringContent(string.Format("grant_type=password&username={0}&password={1}", HttpUtility.UrlEncode(username), HttpUtility.UrlEncode(password)), Encoding.UTF8, "application/x-www-form-urlencoded")).Result; string resultJSON = response.Content.ReadAsStringAsync().Result; AuthTokenModel result = JsonConvert.DeserializeObject(resultJSON); return result; } using Newtonsoft.Json; public class AuthTokenModel { public override string ToString() { return AccessToken; } [JsonProperty(PropertyName = "access_token")] public string AccessToken { get; set; } [JsonProperty(PropertyName = "error")] public string Error { get; set; } [JsonProperty(PropertyName = "error_description")] public string ErrorDescription { get; set; } } //you can add the auth token to your httpclient headers like so: _HttpClient.DefaultRequestHeaders.Add("Authorization", "Bearer " + token);

Read

I use this function to get content, the path would be as follows: https://www.mysite.com/umbraco/rest/v1/content/12345. The content is always formatted according to the HAL specification so I created a base object with all the generic properties which I then extend to add in the custom properties for each doc type.

internal async Task<T> GetResource(string path) { var httpClient = GetHttpClient(); var response = await httpClient.GetAsync(new Uri(path)); var jsonString = await response.Content.ReadAsStringAsync(); var mapped = JsonConvert.DeserializeObject(jsonString, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); return mapped; }

Update

When updating you need to post to the same url that you would to read, with the changed properties updated on your payload. The path would be the same as read: “https://www.mysite.com/umbraco/rest/v1/content/12345”

internal async Task<T> PutResource<T>(string path, T data) { var httpClient = GetHttpClient(); var response = await httpClient.PutAsJsonAsync(path, data); var responseData = await response.Content.ReadAsAsync<T>(); return responseData; }

Create

When creating content you simply post to the base url but you need to set some properties as a minimum in order to create. You can refer to the content service docs to see what you need as this is what is used behind the scenes. (Hint: its name, parent id and content type alias thats needed). The path would be something like: “https://www.mysite.com/umbraco/rest/v1/content/”

internal async Task<T> PostResource<T, K>(string path, K data) { var httpClient = GetHttpClient(); var response = await httpClient.PostAsJsonAsync(path, data); var responseData = await response.Content.ReadAsAsync<T>(); return responseData; }

Delete

Deleting unfortunately isn’t implemented in the current version of the REST API, if you’re crafty however and check out the pull requests on the github repo you can see how someone has implemented it. The path to this could be: “https://www.mysite.com/umbraco/rest/v1/content/12345”

internal async Task<bool> DeleteResource(string path, int id) { var httpClient = GetHttpClient(); var response = await httpClient.DeleteAsync(path + "/" + id); return response.IsSuccessStatusCode; }

This is just the basics, there is much more to the API but hopefully this will get you started!