Developers Guide To Sitecore - Services.client sc75 A4
Developers Guide To Sitecore - Services.client sc75 A4
5 or later
Developer's Guide to Sitecore.Services.Client Rev: 18 September 2015
Developer's Guide to
Sitecore.Services.Client
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Sitecore® Experience Platform™ 7.5 or later
Table of Contents
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 2 of 58
Developer's Guide to Sitecore.Services.Client
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 3 of 58
Sitecore® Experience Platform™ 7.5 or later
Chapter 1
This chapter gives you an overview and an introduction. It contains the following
section:
What is Sitecore.Services.Client?
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 4 of 58
Developer's Guide to Sitecore.Services.Client
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 5 of 58
Sitecore® Experience Platform™ 7.5 or later
Chapter 2
Security
Overview
Security Policies
Authorization Filters
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 6 of 58
Developer's Guide to Sitecore.Services.Client
2.1 Overview
The Entity and ItemServices use the Web API ActionFilters to determine whether they handle or reject
a request. You can read about ActionFilters at MSDN: http://msdn.microsoft.com/en-
us/library/system.web.http.filters.actionfilterattribute.aspx.
Sitecore.Services.Client provides two layers of security:
1. A security policy that applies to all Sitecore.Services.Client requests
2. Individual filters which add additional requirements on requests that are to be executed
The ItemService has some additional security settings, see ItemService Security.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 7 of 58
Sitecore® Experience Platform™ 7.5 or later
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 8 of 58
Developer's Guide to Sitecore.Services.Client
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 9 of 58
Sitecore® Experience Platform™ 7.5 or later
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 10 of 58
Developer's Guide to Sitecore.Services.Client
Chapter 3
The ItemService
Introduction
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 11 of 58
Sitecore® Experience Platform™ 7.5 or later
3.1 Introduction
The ItemService provides a single HTTP endpoint and API to interact with Sitecore items over HTTP.
Sitecore.Services.Client ships with routes predefined to interact with the ItemService, and you do not
need to do any server-side development to use the ItemService.
You can use the ItemService in three ways:
You can use it in SPEAK applications, using the StoredQueryDataSource data source. When
you use the ItemService this way, it is completely transparent.
You can use the ItemService from client-side JavaScript (in the browser).
You can use the RESTful API to access Sitecore items directly.
3.1.1 Implementation
The
Sitecore.Services.Infrastructure.Sitecore.Controllers.ItemServiceController
class implements the service. We have sealed the class itself so that other classes cannot inherit from
it. Only one single instance of the ItemService is supposed to run in a Sitecore website.
• ItemID
• ItemName
• ItemPath
• ParentID
• TemplateID
• TemplateName
• CloneSource
• ItemLanguage
• ItemVersion
• DisplayName
• HasChildren
• ItemIcon
• ItemMedialUrl
• ItemUrl
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 12 of 58
Developer's Guide to Sitecore.Services.Client
Authentication
The ItemService provides two routes for authentication:
auth/login
auth/logout
You must make requests to auth/login over HTTPS.
When you make requests to this route from JavaScript, you must load the whole page over HTTPS to
avoid the request failing because it is Cross-Origin.
Anonymous Access
The default is that the extranet\Anonymous user does not have access to the ItemService. You
set this behavior with the Sitecore.Services.AllowAnonymousUser setting in the
Sitecore.Services.Client configuration file.
When you set Sitecore.Services.AllowAnonymousUser to true, then the ItemService will run
anonymous requests in the security context of the user defined in the
Sitecore.Services.AnonymousUser configuration setting. Such requests will, by default, do
user impersonation and run as the sitecore\ServicesAPI user.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 13 of 58
Sitecore® Experience Platform™ 7.5 or later
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 14 of 58
Developer's Guide to Sitecore.Services.Client
Unit.js
Many of the examples user functionality from Unit.js. If you want to run the examples literally, you
must add a reference to Unit.js in your code.
var aNewGuy = {
name: "David",
isActive: true,
gender: "male"
};
david.should.be.an.instanceOf( ItemService.Item );
david.name.should.eql( "David" );
david.isActive.should.eql( true );
david.gender.should.eql( "male" );
done();
} ).fail( done );
peopleService.create().then( function () {
done();
} ).fail( done );
melton.should.be.an.instanceOf( ItemService.Item );
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 15 of 58
Sitecore® Experience Platform™ 7.5 or later
melton.should.be.an.instanceOf( ItemService.Item );
melton.fetchChildren().execute().then( function ( meltonsChildren ) {
meltonsChildren.should.be.an.Array.and.have.a.lengthOf( 3 );
meltonsChildren[ 0 ].should.be.an.instanceOf( ItemService.Item );
meltonsChildren[ 1 ].should.be.an.instanceOf( ItemService.Item );
meltonsChildren[ 2 ].should.be.an.instanceOf( ItemService.Item );
done();
} ).fail( done );
} ).fail( done );
melton.should.be.an.instanceOf( ItemService.Item );
melton.name = "Melton the Magnificent";
} ).fail( done );
} ).fail( done );
melton.should.be.an.instanceOf( ItemService.Item );
melton.destroy().execute().then( function () {
done();
} ).fail( done );
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 16 of 58
Developer's Guide to Sitecore.Services.Client
done();
} ).fail( done );
done();
} ).fail( done );
“xxxx-xxxx-xxxx-xxxx” is the Sitecore ID of the query item (see Run a Stored Query for details).
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 17 of 58
Sitecore® Experience Platform™ 7.5 or later
} ).fail( done );
guy.isNew.should.be.true;
done();
} ).fail( done );
peopleService.create( {
name: "guy"
} ).execute().then( function ( guy ) {
guy.isNew.should.be.false;
done();
} ).fail( done );
melton.should.be.an.instanceOf( ItemService.Item );
meltonAsJSON.should.be.an.instanceOf( Object );
meltonAsJSON.should.not.be.an.instanceOf( ItemService.Item );
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 18 of 58
Developer's Guide to Sitecore.Services.Client
done();
} ).fail( done );
/* Listening to the `save` event `once`. You can also use `on` here to continuously listen
to the `save` event. */
melton.once( "save", function ( error ) {
done();
} );
} ).fail( done );
melton.hasChanged().should.be.false;
melton.name = "Melton the Magnificent";
melton.hasChanged().should.be.true;
done();
} ).fail( done );
The hasChanged method does not return true if a value changes between null, undefined and ‘’ (the
empty string):
var peopleService = new ItemService( {
url: "/sitecore/api/ssc/people"
} );
melton.hasChanged().should.be.false;
melton.subscribed = "";
melton.hasChanged().should.be.false;
melton.subscribed = null;
melton.hasChanged().should.be.false;
melton.subscribed = undefined;
melton.hasChanged().should.be.false;
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 19 of 58
Sitecore® Experience Platform™ 7.5 or later
done();
} ).fail( done );
done();
} ).fail( done );
The query object has chainable helper methods. These methods add the given value to the query
string of the request:
var peopleService = new ItemService( {
url: "/sitecore/api/ssc/people"
} );
peopleService.create( {} )
.database( "master" )
.facet( "a facet" )
.fields( "ItemName" )
.includeMetadata( true )
.includeStandardTemplateFields( true )
.language( "en" )
.page( 2 )
.path( "/sitecore/content/home" )
.sort( "aItemName" )
.take( 5 )
.version( "latest" )
.should.be.an.instanceOf( ItemService.Query );
You call the execute() method to run the query. The execute() method returns a promise:
var peopleService = new ItemService( {
url: "/sitecore/api/ssc/people"
} );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 20 of 58
Developer's Guide to Sitecore.Services.Client
melton.should.be.an.instanceOf( ItemService.Item );
done();
} ).fail( done );
fetchQueryPromise.should.have.a.property( "then" );
fetchQueryPromise.should.have.a.property( "fail" );
} );
When you have integrated middleware as in the previous example, then the next time you receive
data from the server, this data will have a “timestamp” property:
var peopleService = new ItemService( {
url: "/sitecore/api/ssc/people"
} );
melton.should.have.a.property( "timestamp" );
done();
} ).fail( done );
Because you cleared all middleware the previous example, the data will not have a timestamp
property next time you receive it from the server:
var peopleService = new ItemService( {
url: "/sitecore/api/ssc/people"
} );
melton.should.have.not.a.property( "timestamp" );
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 21 of 58
Sitecore® Experience Platform™ 7.5 or later
url: "/sitecore/api/ssc/people"
} );
done();
} );
melton.age = 40;
melton.save().execute();
} ).fail( done );
error.should.be.an.instanceOf( Error );
done();
} );
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 22 of 58
Developer's Guide to Sitecore.Services.Client
3.4.1 Authentication
Login
You use this method to authenticate users. It sets the .ASPXAUTH cookie. This method only
responds over HTTPS.
Verb POST
URL /auth/login
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://<your server>/sitecore/api/ssc/auth/login");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send("{ \n \"domain\": \"sitecore\", \n \"username\": \"admin\", \n \"password\":
\"b\" \n}");
The ItemService sends 200 (OK) when successful and 403 (Forbidden) when the login did not
succeed.
Logout
You use this method to log out of Sitecore. It removes the .ASPXAUTH cookie.
Verb POST
URL /auth/logout
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://<your server>/sitecore/api/ssc/auth/logout");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
The ItemService sends 200 (OK) when successful and 403 (Forbidden) when the logout did not
succeed.
Verb GET
URL /item/{id}?database&language&version&includeStandardTemplateFields&includeMetadata&fields
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 23 of 58
Sitecore® Experience Platform™ 7.5 or later
guid, required
id Specify the id of the example: 110D559F-DEA5-42EA-9C1C-
Sitecore item to retrieve. 8A5DF7E70EF9
string, optional
Specify the database to example: core
database
retrieve the item from. default: context database for the logged in
user
string, optional
Select a language. You
example: ja-JP
language can use all as a
default: context language for the user that
wildcard.
is logged in
string, optional
Select the version of the
version example:
item to retrieve.
default: latest version
string, optional
Specify the names of the
example:
fields fields to retrieve in a
ItemId,ItemName,TemplateName
comma-separated list.
default: all fields
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://<your server>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-
8A5DF7E70EF9");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 24 of 58
Developer's Guide to Sitecore.Services.Client
Verb GET
URL /item/?path={path}?database&language&version&includeStandardTemplateFields&includeMetadata&fields
The URL has these parameters:
string, optional
Specify the database to example: core
database
retrieve the item from. default: context database for the logged in
user
string, optional
Select a language. You
example: ja-JP
language can use all as a
default: context language for the user that
wildcard.
is logged in
string, optional
Select the version of the
version example:
item to retrieve.
default: latest version
string, optional
Specify the names of the
example:
fields fields to retrieve in a
ItemId,ItemName,TemplateName
comma-separated list.
default: all fields
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://<your
server>/sitecore/api/ssc/item/?path=%2Fsitecore%2Fcontent%2FHomedatabase");
xhr.onreadystatechange = function () {
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 25 of 58
Sitecore® Experience Platform™ 7.5 or later
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
The response is the same as when you retrieve the item by ID.
Verb GET
URL /item/{id}/children?database&language&version&includeStandardTemplateFields&includeMetadata&fields
The URL has these parameters:
guid, required
id Specify the id of the example: 110D559F-DEA5-42EA-9C1C-
Sitecore items to retrieve. 8A5DF7E70EF9
string, optional
Specify the database to example: core
database
retrieve the items from. default: context database for the logged in
user
string, optional
Select a language. You
example: ja-JP
language can use all as a
default: context language for the user that
wildcard.
is logged in
string, optional
Select the version of the
version example:
items to retrieve.
default: latest version
string, optional
Specify the names of the
example:
fields fields to retrieve in a
ItemId,ItemName,TemplateName
comma-separated list.
default: all fields
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://<your server>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-
8A5DF7E70EF9/children");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 26 of 58
Developer's Guide to Sitecore.Services.Client
};
xhr.send(null);
The response is similar to the response you get when you retrieve a single item.
Verb POST
URL /item/{path}?database&language
The URL has these parameters:
string, optional
example: core
database Specify the database to retrieve the items from.
default: context database for the logged
in user
string, optional
Select a language. You can use all as a example: ja-JP
language
wildcard. default: context language for the user that
is logged in
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://<your server>/sitecore/api/ssc/item/sitecore%2Fcontent%2Fhome ");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send("{ \n \"ItemName\": \"Home\", \n \"TemplateID\": \"76036f5e-cbce-46d1-af0a-
4143f9b557aa\", \n \"Title\": \"Sitecore\", \n \"Text\":
\"\\r\\n\\t\\t\u003Cp\u003EWelcome to Sitecore\u003C/p\u003E\\r\\n\" \n}");
If the Sitecore creates the item, you get a response similar to this:
201 (Created)
Location: /item/0727f965-2338-43cc-bd88-5071ad3f7a12?database=master
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 27 of 58
Sitecore® Experience Platform™ 7.5 or later
Verb PATCH
URL /item/{id}?database&language&version
The URL has these parameters:
guid, required
Specify the id of the Sitecore item you want to
id example: 110D559F-DEA5-42EA-9C1C-
edit.
8A5DF7E70EF9
string, optional
database Specify the database the item is in. example: core
default: context database for the logged in user
string, optional
Specify a language selector. You can use all as
language example:
a wildcard.
default: context language for the logged in user
string, optional
version Specify the version of the item you want to edit. example:
default: latest version
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("PATCH", "http://<your server>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-
8A5DF7E70EF9");
xhr.setRequestHeader("Content-Type", "application/json");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send("{ \n \"ParentID\": \"b974fd33-c72e-4bae-a2da-b94fe44f3d6b\", \n
\"ItemName\":\"Home Renamed\", \n \"Title\":\"Sitecore Modified\" \n}");
Verb DELETE
URL /item/{id}?database&language
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 28 of 58
Developer's Guide to Sitecore.Services.Client
guid, required
Specify the id of the Sitecore item you want to
id example: 110D559F-DEA5-42EA-9C1C-
delete.
8A5DF7E70EF9
string, optional
database Specify the database the item is in. example: core
default: context database for the logged in user
string, optional
Specify a language selector. You can use all as
language example: ja-JP
a wildcard.
default: context language for the logged in user
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("DELETE", "http://<your server>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-
8A5DF7E70EF9");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
Verb GET
URL /item/{id}/query?pageSize&page&database&includeStandardTemplateFields&fields
The URL has these parameters:
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 29 of 58
Sitecore® Experience Platform™ 7.5 or later
response.
string, optional
example: core
database Specify the database the item is in.
default: context database for
the logged in user
string, optional
example:
Specify the names of the fields to
fields ItemId,ItemName,Templa
retrieve in a comma-separated list.
teName
default: all fields
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://<your server>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-
8A5DF7E70EF9/query");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
If your request does not succeed, you can get one of these responses:
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 30 of 58
Developer's Guide to Sitecore.Services.Client
400 (Bad Request – this indicates that the request is not accepted by the server. It can be
that a parameter is invalid. It also indicates that the request should not repeated. You get this
response when if the query definition item does not exist.)
403 (Forbidden – the request is not permitted for security reasons.)
Verb GET
URL /item/?term&pageSize&page&database&language&includeStandardTemplateFields&fields&sorting&facet
The URL has these parameters:
string, required
term Specify the text to search for.
example: Home
string, optional
Specify the database the item
database example: core
is in.
default: context database for the logged in user
string, optional
Specify a language selector.
language example: ja-JP
You use all as a wildcarc.
default: context language for the logged in user
string, optional
Specify the names of the
example:
fields fields to retrieve in a comma-
ItemId,ItemName,TemplateName
separated list.
default: all fields
string, optional
facet Specify the name and value example: _templatename|condition
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 31 of 58
Sitecore® Experience Platform™ 7.5 or later
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("GET", "http://<your
server>/sitecore/api/ssc/item/?term&pageSize&page&database&language&includeStandardTemplateFie
lds&fields&sorting&facet");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
If your request does not succeed, you can get one of these responses:
400 (Bad Request)
403 (Forbidden)
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 32 of 58
Developer's Guide to Sitecore.Services.Client
Verb GET
URL /item/{id}/search?term&pageSize&page&database
The URL has these parameters:
guid, required
Specify the id of the search
Id example: 110D559F-DEA5-42EA-9C1C-
definition item.
8A5DF7E70EF9
string, required
term Specify the text to search for.
example: Home
string, optional
Specify the database the item
database example: core
is in.
default: context database for the logged in user
JavaScript example:
var xhr = new XMLHttpRequest();
xhr.open("GET", "<your server>/sitecore/api/ssc/item/110D559F-DEA5-42EA-9C1C-
8A5DF7E70EF9/search?term&pageSize&page&database");
xhr.onreadystatechange = function () {
if (this.readyState == 4) {
alert('Status: '+this.status+'\nHeaders:
'+JSON.stringify(this.getAllResponseHeaders())+'\nBody: '+this.responseText);
}
};
xhr.send(null);
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 33 of 58
Sitecore® Experience Platform™ 7.5 or later
"Link": {
"Href": "http://<your
server>/sitecore/api/ssc/item/search?includeStandardTemplateFields=False&fields=ItemName%2CTem
plateName&term=sitecore&facet=_templatename%7Ccondition",
"Rel": "_templatename|condition",
"Method": "GET"
}
}
]
}
],
"TotalCount": 15,
"TotalPage": 8,
"Links": [
{
"Href": "http://<your
server>/sitecore/api/ssc/item/search?includeStandardTemplateFields=False&fields=ItemName%2CTem
plateName&page=1&term=sitecore&facet=_templatename%7Ccondition",
"Rel": "nextPage",
"Method": "GET"
}
],
"Results": [
{
"ItemName": "Country",
"TemplateName": "Condition"
},
{
"ItemName": "Page was Visited",
"TemplateName": "Condition"
}
]
}
If your request does not succeed, you can get one of these responses:
400 (Bad Request – this indicates that the request is not accepted by the server. It can be
that a parameter is invalid. It also indicates that the request should not repeated. You get this
response when if the query definition item does not exist.)
403 (Forbidden – the request is not permitted for security reasons.)
503 (Service Unavailable)
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 34 of 58
Developer's Guide to Sitecore.Services.Client
Chapter 4
The EntityService
Introduction
EntityService Validation
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 35 of 58
Sitecore® Experience Platform™ 7.5 or later
4.1 Introduction
You can use the EntityService in three ways:
You can use it through the EntityDataSource in SPEAK applications.
You can the EntityService from client-side JavaScript.
You can use the RESTful API to access your business objects directly.
Remember that Sitecore does not provide any business objects. It is up to you to implement the
business objects for the EntityService, but the EntityService implementation provides scaffolding that
makes it easier for you to implement the business objects you need.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 36 of 58
Developer's Guide to Sitecore.Services.Client
public ExampleController()
: this(new ExampleRepository())
{
}
}
2. Implement the following abstract and virtual methods to provide the code to map between your
business object properties and the fields of an item:
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 37 of 58
Sitecore® Experience Platform™ 7.5 or later
You specify the Sitecore Template type and content root to store the items under as constructor
parameters when creating the
Sitecore.Services.Contrib.Data.SitecoreItemRepository<T> derived type:
protected override Category CreateModelFrom(Item item) protected override string GetItemName(T
entity) protected override void UpdateFields(T entity, Item item)
where T : Sitecore.Services.Core.Model.EntityIdentity
Member of
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 38 of 58
Developer's Guide to Sitecore.Services.Client
Server-side Implementation
1. Define a validator by creating a class that derives from
System.ComponentModel.DataAnnotations.ValidationAttribute and implement
your custom validation logic.
The MSDN article How to: Customize Data Field Validation in the Data Model Using Custom
Attributes contains useful information.
2. Define a metadata emitter by creating a class that derives from
Sitecore.Services.Core.MetaData.ValidationMetaDataBase<T> where <T> is
your validator type. You can override the virtual method
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 39 of 58
Sitecore® Experience Platform™ 7.5 or later
Client Implementation
The JavaScript library that interacts with the EntityService needs to know how to handle all the
validators that are in the site for client-side validation to work. When you add a custom validator, you
need to supply a client-side implementation of the validation logic.
You put the client-side validation logic in a JavaScript file in the folder specified by the
Sitecore.Extensions.Validation.FolderPath configuration setting. The default setting is
\sitecore\shell\client\Services\Assets\lib\extensions\validators.
When the EntityService JavaScript library first meets a custom validator in the service metadata
response, it will make a call to the MetaDataScript controller (sitecore/api/ssc/script/metadata) to
retrieve the JavaScript file that contains the client-side logic for that validation attribute.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 40 of 58
Developer's Guide to Sitecore.Services.Client
In production environments, we recommend that you use a more restrictive definition of what can to
access resources.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 41 of 58
Sitecore® Experience Platform™ 7.5 or later
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 42 of 58
Developer's Guide to Sitecore.Services.Client
var entityMetadata = {
"entity": {
"key": "Id",
"properties": [
{
"key": "Name",
"datatype": "string",
"validators": []
},
{
"key": "Authors",
"datatype": [
[
{
"key": "Name",
"datatype": "string",
"validators": []
},
{
"key": "Address",
"datatype": [
{
"key": "Postcode",
"datatype": "string",
"validators": []
}
],
"validators":[]
}
]
],
"validators":[]
},
{
"key":"Created",
"datatype":"datetime",
"validators":[]
},
{
"key":"State",
"datatype":"number",
"validators":[]
},
{
"key":"Id",
"datatype":"string",
"validators":[]
},
{
"key":"Url",
"datatype":"string",
"validators":[]
}
]
}
};
EntityServiceJS sanitizes your data based on the metadata the server sends.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 43 of 58
Sitecore® Experience Platform™ 7.5 or later
}
},
{
"FetchEntity": {
"returnType": entityType",
"properties": {
"key": "id",
"datatype": "Guid"
}
}
}
],
"POST": {
"CreateEntity": {
"returnType": "void",
"properties": {
"key": "entity",
"datatype": "entityType"
}
}
},
"PUT": {
"UpdateEntity": {
"returnType": "void",
"properties": {
"key": "entity",
"datatype": "entityType"
}
}
},
"DELETE": {
"Delete": {
"returnType": "void",
"properties": {
"key": "entity",
"datatype": "entityType"
}
}
}
}
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 44 of 58
Developer's Guide to Sitecore.Services.Client
"param": [
0,
50
]
}
]
},
{
"key": "Address",
"datatype": [
{
"key": "Postcode",
"datatype": "string",
"validators": []
}
],
"validators": []
}
]
],
"validators": []
},
{
"key": "Id",
"datatype": "string",
"validators": []
},
{
"key": "Url",
"datatype": "string",
"validators": []
}
]
}
Note
You must derive all C# entity types that the EntityService handles from
Sitecore.Services.Core.Model.EntityIdentity.
Note: guid is not a JavaScript data type but the EntityService JavaScript layer understand that it is
an identity type and it is treats it accordingly.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 45 of 58
Sitecore® Experience Platform™ 7.5 or later
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 46 of 58
Developer's Guide to Sitecore.Services.Client
4.6.1 Promises
Almost all asynchronous calls (typically execute()) return a promise. EntityService uses the “q”
module to handle promises:
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
fetchQueryPromise.should.have.a.property( "then" );
fetchQueryPromise.should.have.a.property( "fail" );
4.6.2 Middleware
You can use middleware with the EntityService with the sc-useify module. You can only inject
middleware after a request has resolved. This gives you the opportunity to modify it just before the
promise is resolved.
EntityService.use( function ( data, next ) {
} );
Because you have integrated middleware in the previous example, the next time data is received from
the server, a timestamp property is added to the data:
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
melton.should.have.a.property( "timestamp" );
done();
} ).fail( done );
You can clear all middleware workers, or you can clear by key:
EntityService.useify.clear();
Because you cleared all middleware in the previous example, the next time data is received from the
server there will not be a timestamp property on the data.
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
melton.should.have.not.a.property( "timestamp" );
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 47 of 58
Sitecore® Experience Platform™ 7.5 or later
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 48 of 58
Developer's Guide to Sitecore.Services.Client
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 49 of 58
Sitecore® Experience Platform™ 7.5 or later
peopleService.createEntity.should.be.a.type( "function" );
peopleService.fetchEntity.should.be.a.type( "function" );
peopleService.fetchEntities.should.be.a.type( "function" );
peopleService.loadMetadata.should.be.a.type( "function" );
The structure of an Entity object is based on metadata (a “schema”). The EntityService will request
this metadata only once from the server, using the OPTIONS request.
Example:
1. An EntityService is instantiated.
2. When the EntityService is asked to execute any server related request (createEntity,
fetchEntity etc), the supplied URL is hit with an OPTIONS method. All subsequent requests
are queued until the server responds with a valid metadata object.
3. After the metadata object is returned, it is attached to context EntityService and all entities
can be validated and sanitized based on this metadata.
The following code examples are based on this metadata:
var metadata = {
"entity": {
"key": "ItemID",
"properties": [ {
"key": "id",
"datatype": "number"
}, {
"key": "ItemID",
"datatype": "guid"
}, {
"key": "isActive",
"datatype": "boolean"
}, {
"key": "balance",
"datatype": "string"
}, {
"key": "picture",
"datatype": "string"
}, {
"key": "age",
"datatype": "number"
}, {
"key": "name",
"datatype": "string"
}, {
"key": "gender",
"datatype": "string"
}, {
"key": "company",
"datatype": "string"
}, {
"key": "email",
"datatype": "email"
}, {
"key": "phone",
"datatype": "string"
}, {
"key": "address",
"datatype": "string"
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 50 of 58
Developer's Guide to Sitecore.Services.Client
}, {
"key": "about",
"datatype": "string"
}, {
"key": "registered",
"datatype": "date"
}, {
"key": "latitude",
"datatype": "number"
}, {
"key": "longitude",
"datatype": "number"
}, {
"key": "subscribed",
"datatype": "string"
}, {
"key": "children",
"datatype": [ {
"properties": [ {
"key": "name",
"datatype": "string"
} ]
} ]
}, {
"key": "tags",
"datatype": [ "string" ]
} ]
}
};
var aNewGuy = {
name: "David",
isActive: "true",
gender: "male"
};
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 51 of 58
Sitecore® Experience Platform™ 7.5 or later
david.isActive.should.eql( true );
david.gender.should.eql( "male" );
/**
* ... and because not all of the key/values for this `Entity` were given based on the
* `peopleService` end point metadata, they will still be added to the `Entity`. Their
default
* values are also based on the metadata.
*/
done();
} ).fail( done );
You can create a dirty entity without having to make a call to the server. You do this by not giving an
object to the createEntity method. All dirty entities are considered new. You can check this with the
isNew property.
david.isNew.should.be.true;
done();
} ).fail( done );
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 52 of 58
Developer's Guide to Sitecore.Services.Client
} );
people.should.be.an.Array.with.a.lengthOf( 3 );
people[ 0 ].isValid().should.be.ok;
people[ 1 ].isValid().should.be.ok;
/*
* The data of people[ 2 ] has been intentionally made invalid
*/
people[ 2 ].isValid().should.not.be.ok;
done();
} ).fail( done );
cooley.should.be.an.instanceOf( EntityService.Entity );
cooley.name = "Mrs Queen Cooley";
} ).fail( done );
} ).fail( done );
Each time you save an Entity, it will trigger a ‘save’ event that you can listen for:
( entity.on(’save’, callback) ).
cooley.should.be.an.instanceOf( EntityService.Entity );
cooley.destroy().then( function () {
done();
} ).fail( done );
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 53 of 58
Sitecore® Experience Platform™ 7.5 or later
done();
} ).fail( done );
} );
4.8.8 isNew
You check if an Entity has not been saved (it is “dirty”) with the isNew property:
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
guy.isNew.should.be.true;
done();
} ).fail( done );
peopleService.createEntity( {
name: "guy"
} ).then( function ( guy ) {
/*
* `guy` is technically from the server because we are creating a new `Entity` by giving an
* object to the `createEntity` method.
*/
guy.isNew.should.be.false;
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 54 of 58
Developer's Guide to Sitecore.Services.Client
queen.should.be.an.instanceOf( EntityService.Entity );
queenAsJson.should.be.an.instanceOf( Object );
queenAsJson.should.not.be.an.instanceOf( EntityService.Entity );
done();
} ).fail( done );
done();
} ).fail( done );
/* Listening to the `save` event `once`. You can also use `on` here to continuously listen
to the `save` event. */
melton.once( "save", function ( error ) {
done();
} );
} ).fail( done );
4.8.12 hasChanged()
When you turn trackable on, the method hasChanged is added so you can check if an Entity has
changed:
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 55 of 58
Sitecore® Experience Platform™ 7.5 or later
melton.hasChanged().should.be.false;
melton.name = "Melton the Magnificent";
melton.hasChanged().should.be.true;
done();
} ).fail( done );
The hasChanged method does not return true if a value changes between null, undefined and ``.
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
melton.hasChanged().should.be.false;
melton.subscribed = "";
melton.hasChanged().should.be.false;
melton.subscribed = null;
melton.hasChanged().should.be.false;
melton.subscribed = undefined;
melton.hasChanged().should.be.false;
done();
} ).fail( done );
4.8.13 revertChanges()
When you turn trackable on, the method revertChanges is added so you can revert your changes.
var peopleService = new EntityService( {
url: "/sitecore/api/ssc/people"
} );
done();
} ).fail( done );
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 56 of 58
Developer's Guide to Sitecore.Services.Client
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 57 of 58
Sitecore® Experience Platform™ 7.5 or later
The default routing configuration does not support a request that does not supply an {id} parameter
(the {namespace}/{controller}/{action} route).
4.9.2 Configuration
The Sitecore.Services.Client.config include file contains the following configuration
options:
A unique name that does not provide both the {namespace} and the {controller} parts will not
be serviced by the {namespace}/{controller}/{action} route, and can generate HTTP 404
responses.
Sitecore® is a registered trademark. All other brand and product names are the property of their respective holders. The
contents of this document are the property of Sitecore. Copyright © 2001-2015 Sitecore. All rights reserved.
Page 58 of 58