september 05, 2017
As we all know, Sitecore is pushing hard to improve the development experience in the headless scenario. While we await the next release and new features, there are at least two ways to facilitate headless development in Sitecore right now. In this post I’ll provide an overview of the Item Service and Sitecore Experience Accelerator (SXA) JSON, providing some thoughts on when each might be appropriate.
Option 1: Item Service
The ItemService is a long standing piece of the platform that provides a developer with a REST API to access Sitecore content for standard CRUD operations. By default, the ItemService endpoint requires authentication, so please check the documentation in the link above to set that up.
The major actions available are summarized below and the full description of parameters are in the referenced link.
Action | HTTP verb |
End Point (all start with /sitecore/api/ssc/) |
Login | POST |
/auth/login |
Logout | POST |
/auth/login |
Read | GET |
/item/(parameters) |
Create | POST | |
Edit | PATCH |
/item/{id}?database&language |
Delete |
DELETE |
/item/{id}?database&language |
Run a stored query | GET |
/item/{id}/query?pageSize&page&database&includeStandardTemplateFields&fields |
Run a search | GET |
/item/?term&pageSize&page&database&language&includeStandardTemplateFields&fields&sorting&facet |
Run a stored search | GET |
/item/{id}/search?term&pageSize&page&database |
Let’s pause here. As you can see from the above list of actions, the ItemService is about data, but if your data it is in Sitecore you can probably get to it from the ItemService. Any presentation logic will be the developer’s complete responsibility.
Sitecore’s built-in data caching will apply inside the ItemService for reads, so do keep in mind that any updates triggered by your DELETE/UPDATE/CREATE may not be immediately visible to a read depending on what database you are acting against.
With this approach you also lose any capabilities inherited in the Experience Platform for personalization, testing and tracking. Now, if the above limitations are not a concern for your application, let’s continue.
Getting Data from Sitecore
We can pull the most commonly needed data from an item – in this case the default home item - with all content fields using the following endpoint call.
http://<hostname>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9
The resulting JSON looks like the following:
{
"ItemID":"110d559f-dea5-42ea-9c1c-8a5df7e70ef9",
"ItemName":"Home",
"ItemPath":"/sitecore/content/Home",
"ParentID":"0de95ae4-41ab-4d01-9eb0-67441b7c2450",
"TemplateID":"76036f5e-cbce-46d1-af0a-4143f9b557aa",
"TemplateName":"Sample Item",
"CloneSource":null,
"ItemLanguage":"en",
"ItemVersion":"1",
"DisplayName":"Home",
"HasChildren":"False",
"ItemIcon":"/~/icon/Network/16x16/home.png.aspx",
"ItemMedialUrl":"/~/icon/Network/48x48/home.png.aspx",
"ItemUrl":"/sitecore/content/DMS-Home.aspx",
"Text":"<p style=\"line-height: 22px;\">From a single connected platform that also integrates with other customer-facing platforms, to a single view of the customer in a big data marketing repository, to completely eliminating much of the complexity that has previously held marketers back, the latest version of Sitecore makes customer experience highly achievable. Learn how the latest version of Sitecore gives marketers the complete data, integrated tools, and automation capabilities to engage customers throughout an iterative lifecycle – the technology foundation absolutely necessary to win customers for life.</p>\n<p>For further information, please go to the <a href=\"https://doc.sitecore.net/\" target=\"_blank\" title=\"Sitecore Documentation site\">Sitecore Documentation site</a></p>",
"Title":"Sitecore Experience Platform"
}
As you can see the response is quite easy to process with the one caveat that link expansion does not occur as a part of the ItemService. Sitecore handles this link expansion in the presentation layer, in particular the field renderers. So, if you have RichText fields you will need to keep this in mind.
Searches and Queries
For those of you that may want to run more complex retrieval operations, the search and query endpoints can be very helpful, especially the search as it lets you limit results on facets.
You can store and run preset queries or searches. The ItemService includes templates at /sitecore/templates/System/Services/Item Service that allow you to store queries and searches.
Query Example
The {id} in the following call being the GUID of your stored query you can retrieve a list of children of home.
/item/{id}/query?pageSize&page&database&includeStandardTemplateFields&fields
The stored query item is created from template /System/Services/Item Service/Query/Query Definition. This allows you to store the Sitecore query and database like so:
The result of running the above is:
{
"TotalCount":2,
"TotalPage":1,
"Links":[
],
"Results":[
{
"ItemID":"6edf0df7-26c6-4077-84fa-3ba890c2a3e1",
"ItemName":"Query Folder",
"ItemPath":"/sitecore/content/Home/Query Folder",
"ParentID":"110d559f-dea5-42ea-9c1c-8a5df7e70ef9",
"TemplateID":"cebf2ea3-e6ee-4564-9d76-f71f431f6af6",
"TemplateName":"Query Folder",
"CloneSource":null,
"ItemLanguage":"en",
"ItemVersion":"1",
"DisplayName":"Query Folder",
"HasChildren":"True",
"ItemIcon":"/temp/iconcache/applications/16x16/folder_view.png",
"ItemMedialUrl":"/~/icon/Applications/48x48/folder_view.png.aspx",
"ItemUrl":"/Error-404.aspx?item=web%3a%7b6EDF0DF7-26C6-4077-84FA-3BA890C2A3E1%7d%40en"
},
{
"ItemID":"a6533534-deff-4372-9bf4-6535adc83ca9",
"ItemName":"Search Folder",
"ItemPath":"/sitecore/content/Home/Search Folder",
"ParentID":"110d559f-dea5-42ea-9c1c-8a5df7e70ef9",
"TemplateID":"3c73488b-1a47-4b9e-8522-27e059b31533",
"TemplateName":"Search Folder",
"CloneSource":null,
"ItemLanguage":"en",
"ItemVersion":"1",
"DisplayName":"Search Folder",
"HasChildren":"True",
"ItemIcon":"/temp/iconcache/applications/16x16/folder_view.png",
"ItemMedialUrl":"/~/icon/Applications/48x48/folder_view.png.aspx",
"ItemUrl":"/Error-404.aspx?item=web%3a%7bA6533534-DEFF-4372-9BF4-6535ADC83CA9%7d%40en"
}
]
}
Search Example
The stored search call:
/item/{id}/search?term&pageSize&page&database
References a Sitecore item based on the template /System/Services/Item Service/Search/Query Definition. This allows you to store database, language, sorting and field settings like so. Note that on field sorting a “a” before the fieldname is ascending and “d” is descending.
Note: the term parameter is required in the call. You can pass a * if desired.
The below screen shot expressed in plain English is search the web database for items with templates of “folder” in the English language and order them by template name ascending then itemid descending. Return only the ItemId, ItemName, TemplateName fields.
The response:
{
"Facets":[
{
"Name":"_templatename",
"Values":[
{
"Name":"sample item",
"AggregateCount":2,
"Link":{
"Href":"http://jss/sitecore/api/ssc/item/%7B5B8482C9-3E2B-44CA-8221-432D7E498A8D%7D/search?IncludeStandardTemplateFields=False&Fields=ItemId%2CItemName%2CTemplateName&facet=_templatename%7Csample%20item",
"Rel":"_templatename|sample item",
"Method":"GET"
}
}
]
}
],
"TotalCount":2,
"TotalPage":1,
"Links":[
{
"Href":"http://jss/sitecore/api/ssc/item/%7B5B8482C9-3E2B-44CA-8221-432D7E498A8D%7D/search?includeStandardTemplateFields=False&fields=ItemId%2CItemName%2CTemplateName&database=web&sorting=aTemplateName%7CdItemId&Term=%2A&facet=_templatename%7Csample%20item&page=1",
"Rel":"nextPage",
"Method":"GET"
}
],
"Results":[
...
]
}
Option 2: SXA JSON
In spring of 2017 Sitecore introduced a feature they termed data modelling to SXA. This feature is comprised of a specialized device, layout and renderings that output any SXA content in a JSON format. As the presentation layer of Sitecore is used to render the JSON you can access the resulting JSON through a simple URL pattern.
Query | Description |
/home?sc_device=json |
Returns the JSON for the page at /home |
/home?sc_device=json&sc_filter_path=/leftph/menu |
Returns a rendering based on a placeholder. |
/home?sc_device=json&sc_filter_id=content,spot1 |
Returns renderings with the ID content and spot1 from the /home page. |
/home?sc_device=json&sc_filter_name=richtext |
Returns renderings of type richtext from the /home page. |
/home?sc_device=json&sc_filter_path=content&sc_filter_name=richtext |
Returns renderings of type richtext in placeholder content from the /home page. |
As the presentation engine is responsible for the JSON rendering the caveats about link expansion and output caching found in the item service are no longer applicable. Personalization and tracking of xDB would also still apply and you can define your own SXA rendering variants to further customize the JSON.
One thing not immediately clear (at least to me) from the documentation is that if you do not add any explicit JSON components to the JSON device, SXA is still capable of outputting most of the contents of the page.
Taking a blank SXA site and adding an image component to the page in the default device, the JSON response for this page at http://<hostname>/?sc_device=json included the fields of the page as well as those for the image component.
{
"name":"Home",
"fields":{
"OpenGraphTitle":"",
"TwitterCardType":"{32F6A4E4-93DD-4A9C-AA60-CDEDB0BEDABB}",
"Priority":"{19F3E919-4991-495F-9207-E1DADFD06F54}",
"NavigationClass":"",
"Content":"<p>Grants home page 12</p>",
"MetaKeywords":"",
"OpenGraphType":"",
"TwitterTitle":"",
"NavigationTitle":"$name",
"NavigationFilter":"",
"TwitterDescription":"",
"Attributes":"",
"OpenGraphDescription":"",
"SxaTags":"",
"OpenGraphImageUrl":{
"rendered":"",
"src":""
},
"Scope":"",
"OpenGraphAdmins":"",
"OpenGraphAppId":"",
"Title":"GBTEST",
"Body Id":"",
"MetaDescription":"",
"ChangeFrequency":"{D23B4654-53A5-4589-8B1B-5665A763D144}",
"TwitterImage":{
"rendered":"",
"src":""
},
"Page Design":"",
"StickyNotes":"{"items":[]}",
"Body Css Class":"",
"OpenGraphSiteName":"",
"TwitterSite":""
},
"components":[
{
"name":"Image",
"path":"main",
"contents":{
"image":{
"fieldType":"image",
"link":"/-/media/23980E87CA7E43238C269A50CCA12975.jpg",
"guid":"{23980E87-CA7E-4323-8C26-9A50CCA12975}"
},
"imagecaption":""
}
}
]
}
This will meet the needs of many SPA’s and other client application. If you need more then you can define variants of the built-in JSON controls. This is already explained by Sitecore in the documentation.
Summary
To summarize, the ItemService and SXA provide different approaches to headless support. If you are using SXA just keep in mind that this is not an either or and you can combine SXA and ItemService if it makes sense.
Item Service |
SXA JSON |
|
CRUD Operations |
Full CRUD | Read only |
Caching Layer |
Data |
Data, Output (HTML/JSON) |
Control of JSON Format |
Limited |
Can customize JSON components |
Access to Sitecore Presentation Layer |
No | Yes |
Support for Personalization |
No | Yes |
Support for Tracking |
No | Yes |
Support for AB/MV Testing |
No | In theory, but tricky |
Implication for Authors |
No |
May need to manually build up the JSON layout in Experience Editor |