Blog

Mura Demystified: The JSON API, Your Next Favorite Thing

November 16, 2017 by Grant Shepert

The best part of Mura is a thing you probably didn't even realize existed. Maybe the double-acronym scared you away, they can be like that.

The JSON (JavaScript Object Notation) API (Application Programming Interface) is a standardized, self-describing, REST-friendly interface for interacting with Mura, and getting it to do amazing stuff too.

Why So Serious?

Having a serious, robust API isn't just important anymore, it's mandatory. The web is evolving fast towards a headless all-the-time-and-everywhere state of being, where content needs to be distributed easily and reliably to any number of known (and more often unknown) interfaces like web browsers, tablets, phones, shared-content peers and distribution networks, in a secure and easily digested format, rendered and.or unrendered.

That's a lot to ask. Luckily, the world is adapting quickly, and there are a number of technologies like Node.js, Angular, React and Ember to name a very few, that enable this sort of environment. But they are like hungry birds, squawking into the void for content. That's where we come in, via the JSON API. It's serious business.

What Can It Do?

To start off, let's take a look at a very simple example:

http://www.getmura.com/index.cfm/_api/json/v1/default/

This URL references the base endpoint of the JSON API. All calls to the API are standards-based, modeled upon REST:


This format will allow for future-safe development, where new versions and formats may be accessed by modifying the URL calls.
If you clicked on the above link, you may have seen something like this:

{
   "data": {
       "entityname": "entityname",
       "links": {
           "self": "http://www.getmura.com/index.cfm/_api/json/v1/default"
       },
       "items": [{
               "entityname": "category",
               "links": {
                   "endpoint": "http://www.getmura.com/index.cfm/_api/json/v1/default/category",
                   "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/category/properties"
               }
           },
           {
               "entityname": "comment",
               "links": {
                   "endpoint": "http://www.getmura.com/index.cfm/_api/json/v1/default/comment",
                   "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/comment/properties"
               }
           },
           {
               "entityname": "content",
               "links": {
                   "endpoint": "http://www.getmura.com/index.cfm/_api/json/v1/default/content",
                   "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/content/properties"
               }
           },
           {
               "entityname": "contentCategoryAssign",
               "links": {
                   "endpoint": "http://www.getmura.com/index.cfm/_api/json/v1/default/contentCategoryAssign",
                   "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/contentCategoryAssign/properties"
               }
           },
           {
               "entityname": "site",
               "links": {
                   "endpoint": "http://www.getmura.com/index.cfm/_api/json/v1/default/site",
                   "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/site/properties"
               }
           }
       ]
   },
   "params": {
       "
entityname": "entityname",
       "
siteid": "default"
   },
   "method": "findAll",
   "
apiversion": "v1"
}

Since I haven't passed the API any parameters, Mura has returned a base description of what is available to us. This self-describing nature is much appreciated, as it provides a lot of context and cues during development.
In the above example, there are several different data containers which are generally universal in any Mura JSON API call:

data: this object will contain any data returned by the request. Commonly it will contain the name of the entity being queried, any self-describing links that can provide more information, and a list of related items
params: these are the parameters taken from the URL request
method: this is the method that Mura used to respond to the request
apiversion: the version of the API that is managing the request
 
In the above example, you see a list of items that can likewise be interacted with. For instance, if you look specifically at the "content" entity:

{
   "entityname": "content",
   "links": {
       "endpoint": "http://www.getmura.com/index.cfm/_api/json/v1/default/content",
       "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/content/properties"
   }
}

... you can see there are two self-described options available, endpoint and properties. For something like content, which is the Mura ORM object related to content pages, the endpoint response will be similar to a feed with no filters applied:

{
   "data": {
      "endindex": 0,
      "startindex": 0,
      "entityname": "content",
      "totalpages": 0,
      "totalitems": 0,
      "links": {
          "entities": "http://www.getmura.com/index.cfm/_api/json/v1/default",
          "self": "http://www.getmura.com/index.cfm/_api/json/v1/default/?&entityname=content&siteid=default&method=findall&pageIndex=0",
          "properties": "http://www.getmura.com/index.cfm/_api/json/v1/default/content/properties"
      },
      "itemsperpage": 20,
      "items": [],
      "pageindex": 0
   },
   "params": {
      "
entityname": "content",
      "
siteid": "default"
   },
   "method": "findAll",
   "
apiversion": "v1"
}

You might be now wondering, where is all the content then? Aha, well, I imagine you have been simultaneously wondering, "um, what about permissions/security?" Well, herein lies the answer to both questions! You don't see any content items (which would be, obviously, inside the items [ ] array) because you are not logged in. This point is very important: all requests to the JSON API are made within the permission architecture of Mura CMS. In other words, if you don't have permission to see or interact with a thing in Mura, you won't be able to see or interact with it through the JSON API.

Also, if you had been logged in (with appropriate permissions), the original endpoint API call performed at the top of the page would have also listed a great many other objects like user and group.
 
Once logged in, you would see a list of items something like this:

{
   "items": [{
       "path": "00000000000000000000000000000000001,EF9F38D5-CE1F-3B40-C653CAF7BA388BAD,9B9D8F90-CB1B-8223-D573E063F87401E3",
       "menutitle": "An Example Page",
       "active": 1,
       "links": {
           "all": "http://getmura.com/index.cfm/_api/json/v1/default/content",
           "site": "http://getmura.com/index.cfm/_api/json/v1/default/site",
           "properties": "http://getmura.com/index.cfm/_api/json/v1/default/content/properties",
           "categoryassignments": "http://getmura.com/index.cfm/_api/json/v1/default/contentCategoryAssign?contenthistid=9BA0CDD0-DBA7-0ECF-3438FC5B3EC94E83",
           "stats": "http://getmura.com/index.cfm/_api/json/v1/default/stats/9B9D8F90-CB1B-8223-D573E063F87401E3",
           "relatedcontent": "http://getmura.com/index.cfm/_api/json/v1/default/content/9B9D8F90-CB1B-8223-D573E063F87401E3/relatedcontent",
           "comments": "http://getmura.com/index.cfm/_api/json/v1/default/comment?contentid=9B9D8F90-CB1B-8223-D573E063F87401E3",
           "self": "http://getmura.com/index.cfm/_api/json/v1/default/content/9B9D8F90-CB1B-8223-D573E063F87401E3",
           "kids": "http://getmura.com/index.cfm/_api/json/v1/default/content?parentid=9B9D8F90-CB1B-8223-D573E063F87401E3",
           "rendered": "http://getmura.com/index.cfm/_api/json/v1/default/content/_path/a-page/an-example-page",
           "parent": "http://getmura.com/index.cfm/_api/json/v1/default/content/EF9F38D5-CE1F-3B40-C653CAF7BA388BAD",
           "crumbs": "http://getmura.com/index.cfm/_api/json/v1/default/content/9B9D8F90-CB1B-8223-D573E063F87401E3/crumbs",
           "entities": "http://getmura.com/index.cfm/_api/json/v1/default",
           "history": "http://getmura.com/index.cfm/_api/json/v1/default/content/9B9D8F90-CB1B-8223-D573E063F87401E3/history"
       },
       "url": "http://getmura.com/index.cfm/a-page/an-example-page/",
       "display": 1,
       "contenthistid": "9BA0CDD0-DBA7-0ECF-3438FC5B3EC94E83",
       "summary": "",
       "images": {},
       "assocurl": "http://getmura.com/index.cfm/a-page/an-example-page/",
       "id": "9B9D8F90-CB1B-8223-D573E063F87401E3",
       "type": "Page",
       "filename": "a-page/an-example-page",
       "displaystart": "",
       "contentid": "9B9D8F90-CB1B-8223-D573E063F87401E3",
       "subtype": "Default",
       "remoteurl": "",
       "changesetid": "",
       "moduleid": "00000000000000000000000000000000000",
       "siteid": "default",
       "remoteid": "",
       "parentid": "EF9F38D5-CE1F-3B40-C653CAF7BA388BAD",
       "displaystop": "",
       "title": "An Example Page",
       "approved": 1,
       "isnew": 0,
       "tags": "",
       "entityname": "contentnav"
   }]
}
 

(The above URL doesn't actually exist, it is used here simply for the sake of example.)
 
You can see that, once you dive down deep enough, you will find a treasure trove of self-described links that give us access to all sorts of information. You can see the content page's category assignments and comments, see a list of kids aka pages below this page, get a JSON-formatted version of the rendered page and a lot more.
 
Again, these requests follow a standardized format:


A Good Start

This is probably a good place to stop for now, as it gives you a lot to explore. In the next Mura Demystified article, I'll look at how you can work more interactively with the JSON API via feeds, iterators, and the by-convention CRUD (create, read, update, delete) functionality. Following that, I will open the book wide on Mura JS, which not only simplifies the permissions of working with the JSON API, but adds a host of other cool features.
 
Once you are up to speed, you'll marvel at the flexibility and possibilities now at your fingertips. That's the great thing about Mura; it lets you choose how you want to work, instead of enforcing a rigid structure that you would otherwise have to work around (or under).