Mike Robbins

Sitecore Developer Blog

Follow me on GitHub

EntityService Sitecore.Services.Client

Sitecore.Services.Client provides a powerful and flexible method of creating Web API based services within Sitecore. Using the provided interfaces and the repository pattern means that you will be building services in a consistent way, allowing you to build more flexible services and reduce the time to develop and maintain them. Sitecore.Services.Client was introduced first in Sitecore 7.5 and supported also in Sitecore 8.

Sitecore.Services.Client consists of two separate services. ItemService which allows you to work with standard Sitecore Item class. The other is EntityService which allows you to work with business entities that you create, and allows you implement the business logic as you require.

Both EntityService and ItemService offers a number of ways of consuming the service, allowing you to work via web requests to the rest API, use the JavaScript API or bind to SPEAK components. This post I will be using the JavaScript API with EntityService in context of an Sitecore SPEAK application.

Model

The first stage of creating a EntityService based service is to create a Model. This model will define your business entity you wish to work with. All Models have to implement the Sitecore.Services.Core.Model.EntityIdentity class.

namespace MikeRobbins.News.Models
{
  public class NewsArticle: Sitecore.Services.Core.Model.EntityIdentity
  {
    public string Title{ get; set; }
    public string Description{ get; set; }
  }
}

Repository

Create a repository based on the IRespository interface. E.g Sitecore.Services.Core.IRepository. Once you implement the interface you can start to code up the functionality that your EntityService will expose.

IRepository will give you methods for Add, Delete, Exists, FindById, GetAll and Update of your Model. You can however extend this if you require.

using MikeRobbins.News.Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Sitecore.Data;

namespace MikeRobbins.News.Repository
{
  public class NewsArticleRepository : Sitecore.Services.Core.IRepository<NewsArticle>
  {
    public void Add(NewsArticle entity)
    {
      throw new NotImplementedException();
    }

    public void Delete(NewsArticle entity)
    {
      throw new NotImplementedException();
    }

    public bool Exists(NewsArticle entity)
    {
      var newsArticle = Sitecore.Data.Database.GetDatabase("Master").GetItem(new ID(entity.Id));
      return newsArticle != null;
    }

    public NewsArticle FindById(string id)
    {
      var newsArticle = Sitecore.Data.Database.GetDatabase("master").GetItem(new ID(id));
      if (newsArticle != null)
      {
        return new NewsArticle() { Id = newsArticle.ID.ToString(), DisplayName = newsArticle.DisplayName };
      }
      else
      {
        return null;
      }
    }
    public IQueryable<NewsArticle> GetAll()
    {
      throw new NotImplementedException();
    }

    public void Update(NewsArticle entity)
    {
    }
 }
}

Controller

Next create a controller and add the ServicesController attribute. Implement the EntiryService class where T is your Model. Create a second constructor that creates new instance of your repository class.

namespace MikeRobbins.News.Controllers
{
  [ValidateAntiForgeryToken]
  [Sitecore.Services.Core.ServicesController]
  public class NewsArticleController : EntityService<NewsArticle>
  {
    public NewsArticleController(IRepository<NewsArticle> repository)
    : base(repository)
    {
    }

    public NewsArticleController()
    : this(new NewsArticleRepository())
    {
    }
  }
}

SPEAK PageCode

Using RequireJS require a reference to the entity service JavaScript library, and update the define element to include the entityService.

require.config({
 paths: {
 entityService: &amp;quot;/sitecore/shell/client/Services/Assets/lib/entityservice&amp;quot;
 }
});

define(["sitecore", "jquery", "underscore", "entityService"], function (Sitecore, $, _, entityService) {
 var News = Sitecore.Definitions.App.extend({
  initialized: function () {
  },
 });
return News;
});

Working with EntityService via the JavaScript API

To work with EntityService via the JavaScript API you create an instance of EntityService passing in the url property. The url property is the url of your controller. EntityService is always prefixed with "/sitecore/api/ssc". The next part of the url is the namespace containing your controller with the "." replaced with "-" followed by your controller name.

E.g. If you your controller is in the namespace MikeRobbins.News.Controllers and called NewsArticleController. Your url would be "/sitecore/api/ssc/MikeRobbins/api/ssc/MikeRobbins-News-Controllers/newsarticlearticle"

Get Entities Example

Create an instance of EntityService with the service url, you can then call fetchEntities. This will then call the GetAll method within your repository defined within the controller. An array of the entities are then returned.

GetNewsArticles: function () {
 var newsService = new entityService({
 url: "/sitecore/api/ssc/MikeRobbins-News-Controllers/newsarticle"
 });

 var result = newsService.fetchEntities().execute().then(function (newsArticles) {
  for (var i = 0; i <= newsArticles.length; i++) {
 var title = newsArticles[i].Title;
}
 });
},

Get Entity Example

Create an instance of EntityService with the service url, you can then call the fetchEntity function passing in an id of an entity. This will then call the FindById method within your repository defined within the controller. An entity class in returned.

GetNewsArticle: function () {
var newsService = new entityService({
 url: "/sitecore/api/ssc/MikeRobbins-News-Controllers/newsarticle"
 });
var result = newsService.fetchEntity("73e3a4fe-7d42-4ed9-b66e-ad948f340f27").execute().then(function (newsArticle) {
 var title = newsArticle.Title;
 });
},

Update Entity Example

Create a an instance of EntityService with the service url, you can then call the fetchEntity function passing in an id of an entity. Once you have an entity returned, make the required changes to the entity. From here you can call the save method, this maps to the update method within the repository. A class is returned containing the updated entity, in the below example I'm popping up a success message in the SPEAK message panel.

UpdateNewsArticle: function () {
var newsService = new entityService({
 url: "/sitecore/api/ssc/MikeRobbins-News-Controllers/newsarticle"
 });

 var result = newsService.fetchEntity("73e3a4fe-7d42-4ed9-b66e-ad948f340f27").execute().then(function (newsArticle) {
  newsArticle.Title = "Hello World";

  newsArticle.save().execute().then(function (savedNewsArticle) {
 messagePanel.addMessage("notification", { text: "Item updated successfully", actions: [], closable: true, temporary: true });
 });
 });
},

Delete Entity Example

Create an instance of EntityService with the service url, you can then call the Delete function passing in the entity to delete. This will then call the delete method within your repository defined within the controller.

DeleteNewsArticle: function () {
var newsService = new entityService({
 url: "/sitecore/api/ssc/MikeRobbins-News-Controllers/newsarticle"
 });
var itemToDelete= {
 Id: itemId>
 };
var result = newsService.delete(itemToDelete).execute().then(function (newsArticle) {
 });
},

Create Entity Example

Create an instance of EntityService with the service url. You can then create a new object populating the properties of your entity. From here you can call CreateEntity, passing in the object you created. This will then call the add method within your repository defined within the controller. A class is returned of the newly created entity.

CreateNewsArticle: function () {
var newsService = new entityService({
 url: &amp;quot;/sitecore/api/ssc/MikeRobbins-News-Controllers/newsarticle&amp;quot;
 });

var exampleNewsArticle = {
 Title: &amp;quot;Hello World&amp;quot;,
 Description:&amp;quot;Some content describing the news article.&amp;quot;;
};

var result = newsService.createEntity(exampleNewsArticle).execute().then(function (newsArticle) {
var title = newsArticle.Title;
 });
},

Tools

There is a few tools you can use to help with debugging and exploring SSC.

  1. Fiddler http://www.telerik.com/fiddler
  2. Kevin Obee's Sitecore Glimpse Plugin. Under Sitecore Tab there is a sitecore services section where you can explore your SSC services.

    Sitecore Glimpse

    Sitecore Glimpse

  3. POSTman https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en
  4. Chrome's Console

Further Reading

Jamie Little has written a useful post on how to add custom Authorisation Filters to the controller to restrict access.

Sitecore services client - Creating a custom authorisation filter

Source

I have an example Sitecore SPEAK application with SSC implemented available on GitHub.  https://github.com/komainu85/SitecoreSPEAKBulkWorkflows/

Master Sitecore

https://youtube.com/watch?v=g0cVr6CnNKM