Ads

Tuesday, 10 May 2016

REST (Representational State Transfer)


REST (Representational State Transfer)
REST service for list was first introduced in SharePoint 2010. It was under the end point/_vti_bin/listdata.svc, and it still works in SharePoint 2013
SharePoint 2013 introduces another endpoint/_api/web/lists, and which is much more powerful than in SharePoint 2010.

Main advantage of REST SP 2013 is using this we can interact remotely with SharePoint data by using any technology that supports REST web requests Open Data Protocol (OData) syntax..
For this we need to construct a RESTful HTTP request, using the Open Data Protocol (OData) standard, which corresponds to the desired client object model API. For example:
Client object model method:
List.GetByTitle(listname)
REST endpoint:
http://server/site/_api/lists/getbytitle('listname')

Note: Client.svc web service in SharePoint handles the HTTP request, and serves the appropriate response in either Atom or JSON (JavaScript Object Notation) format.

By using HTTP requests, you can use these REST endpoints to perform typical CRUD operations against SharePoint entities.

to do this to an endpoint
HTTP request

Read
GET

Create / Update
POST
For POST operations, any properties that are not required are set to their default values. If you attempt to set a read-only property as part of a POST operation, the service returns an exception.
Update / Insert
PUT / MERGE
·         For MERGE requests, setting properties is optional; any properties that you do not explicitly set retain their current property.
·         For PUT requests, if you do not specify all required properties in object updates, the REST service returns an exception. In addition, any optional properties you do not explicitly set are set to their default properties.
Delete
DELETE
For recyclable objects like lists, files & list items, this results in a Recycle operation.

Construct REST URLs to access SharePoint resources

The main entry points for the REST service represent the site collection and site of the specified context.
Before you can access a SharePoint resource using the REST service, you first have to figure out the URI endpoint that points to that resource.

However URI for these REST endpoints closely mimics the API signature of the resource in the SharePoint client object model. (In some cases, however, the endpoint URI differs from the corresponding client object model signature)
Example

Client object model method:    List.GetByTitle(listname).GetItems()
REST endpoint:                         http://server/site/_api/lists/getbytitle('listname')/items

SharePoint REST URI syntax structure (Some endpoints for SharePoint resources deviate from this syntax structure)

SharePoint REST request syntax

To construct a REST endpoint, Follow these steps

·         Start with the REST service reference:   
o    http://server/site/_api
·         Specify the appropriate entry point:     
o    http://server/site/_api/web
·         Navigate from the entry point to the specific resources you want to access:
o    This includes specifying parameters for endpoints that correspond to methods in the client OM.
o    http://server/site/_api/web/lists/getbytitle('listname')
·          

The REST service is part of the client.svc web service So REST service uses _api to which abstract away the need to explicitly reference the client.svc web service. You can also use client.svc in endpoint URI.
URLs have a 256 character limit, so using _api shortens the base URI,

http://server/site/_api/web/lists
Same as
http://server/site/_vti_bin/client.svc/web/lists

The main entry points for the REST service represent the site collection and site of the specified context. In this way, these entry points correspond to theClientContext.Site property and ClientContext.Web property in the client object models.

Access a specific site collection: http://serverName/siteNameOrSitePath/_api/site
To access a specific site : http://serverName/siteNameOrSitePath/_api/web

Entry Points for REST
Access Point
site collection
http://server/site/_api/site
Web
http://server/site/_api/web
User Profile
http:// server/site/_api/SP.UserProfiles.PeopleManager
Search
http:// server/site/_api/search
Publishing
http:// server/site/_api/publishing
all lists in a site and adding new lists
/_api/Web/Lists
Get list by title & Update
/_api/Web/Lists/GetByTitle('listname') or
/_api/Web/Lists(guid'guid id of your list')
All fields of a list and add new fields
/_api/Web/Lists/GetByTitle(' listname ')/Fields
details of a field, modifying and deleting it
/_api/Web/Lists/GetByTitle('listname')/Fields/GetByTitle('fieldname')
All items in a list and adding new items
/_api/Web/Lists/GetByTitle('listname')/Items
get, update and delete a single item.
/_api/web/lists/GetByTitle('listname')/GetItemById(itemId)
The users in the site
_api/web/siteusers
The user groups in the site
_api/web/sitegroups
The users in group 3
_api/web/sitegroups(3)/users
The root folder of the Shared Documents library
_api/web/GetFolderByServerRelativeUrl('/Shared Documents')
The file a.txt from the Plans library
_api/web/GetFolderByServerRelativeUrl('/Plans')/Files('a.txt')/$value



Now navigate to the specific resources you want to access:

Construct more specific REST endpoints by using the names of the APIs from the client object model separated by a forward slash (/). Below is the examples of client object model calls and the equivalent REST endpoint

Client Object model API
REST Endpoint
ClientContext.Web.Lists
http://server/site/_api/web/lists
ClientContext.Web.Lists[guid]
http://server/site/_api/web/lists(‘guid’)
ClientContext.Web.Lists.GetByTitle("Title")
http://server/site/_api/web/lists/getbytitle(‘Title’)

Options for Filtering and Sorting Data

Option
Purpose
$select
Specifies which fields are included in the returned data.
$filter
Specifies which members of a collection, such as the items in a list, are returned.
$expand
Specifies which projected fields from a joined list are returned.
$top
Returns only the first n items of a collection or list.
$skip
Skips the first n items of a collection or list and returns the rest.
$orderby
Specifies the field that’s used to sort the data before it’s returned.


·         return the author, title and ISBN from a list
o    _api/web/lists/getByTitle('Books')/items?$select=Author,Title,ISBN
o    If wants to return resource-intensive fields then use $select=‘*’
·         get all the books by Mark Twain
o    _api/web/lists/getByTitle('Books')/items?$filter=Author eq 'Mark Twain'
·         To sort the books by title in ascending order
o    _api/web/lists/getByTitle('Books')/items?$orderby=Title asc
·         get only the Title of the first two books by Mark Twain,
§  _api/web/lists/getByTitle('Books')/items?$select=Title&$filter=Author eq 'Mark Twain'&$top=2
·         returns items 3-10
o    _api/web/lists/getByTitle('Books')/items?$top=10&$skip=2
·         returns items 3-12
o    _api/web/lists/getByTitle('Books')/items?$skip=2&$top=10
·         gets the bottom two items
o    _api/web/lists/getByTitle('Books')/items?$orderby=ID desc&$top=2
·         If lookup field Use $expand option, Lets if the Books list has a PublishedBy field that looks up to the Name field of a Publisher list
o    _api/web/lists/getByTitle('Books')/items?$select=Title,PublishedBy/Name&$expand=PublishedBy
·          
·          



Few Examples

GET Items from List

var urlForAllItems = "/_api/Web/Lists/GetByTitle('ListName')/Items";
Then call method - getItems(urlForAllItems);
function getItems(url) {
    $.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + url,
        type: "GET",
        headers: {
            "accept": "application/json;odata=verbose",
        },
        success: function (data) {
            console.log(data.d.results);
        },
        error: function (error) {
            alert(JSON.stringify(error));
        }
    });
}

_spPageContextInfo.webAbsoluteUrl, returns the current site url.
From data.d.results, you will find fields internal names as object’s property. From above we will get only the Id of Lookup and Person type column, but we need more info for them.
So we can use $select, $expand option of OData query string operators

var urlForAllItems = "/_api/Web/Lists/GetByTitle('SpTutorial')/Items?"+
               "$select=ID,Title,SpMultiline,SpChoice,
               SpNumber,SpCurrency,SpDateTime,SpCheckBox,SpUrl,"+
                "SpPerson/Name,SpPerson/Title,SpLookup/Title, SpLookup/ID" +
                "&$expand=SpLookup,SpPerson";

We can also use $filter to specifies which items to return.

var urlForFilteredItems = abovestring + "&$filter=Title eq 'RK' and SpLookup/ID eq 1";

Numeric String Date Time functions
Lt (less than) startsWith (if starts with some string value) day()
Le (less than or equal) substringof ( if contains any sub string) month()
Gt (greater than)
year()
Ge (greater than or equal)
hour()
Eq (equal to) Eq minute()
Ne (not equal to) Ne second()
Note: Unfortunately, date time functions do not work with new style (URL) of SharePoint 2013. But there is a hope we can do it like SharePoint 2010 style.
var filterByMonth = "/_vti_bin/listdata.svc/SpTutorial?$filter=month(SpDateTime) eq 6";

Can use $orderby to sort items: var urlForOrderBy = above url + “&$orderby=ID desc";
Can use $top to: var urlForOrderBy = above url + “/_api/Web/Lists/GetByTitle
('SpTutorial')/Items?$top=2"


Adding New item to List
var addNewItemUrl = "/_api/Web/Lists/GetByTitle('ListName')/Items";

var data = {
    __metadata: { 'type': 'SP.Data.SpTutorialListItem' },
    Title: 'Some title',
    SpMultiline: 'Put here some multiline text. You can add here some rich text also',
    SpChoice: 'Choice 3',
    SpNumber: 5,
    SpCurrency: 34,
    SpDateTime: new Date().toISOString(),
    SpCheckBox: true,
    SpUrl: {
        __metadata: { "type": "SP.FieldUrlValue" },
        Url: "http://test.com",
        Description: "Url Description"
    },
    SpPersonId: 3,
    SpLookupId: 2
};

function addNewItem(url, data) {
    $.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + url,
        type: "POST",
        headers: {
            "accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val(),
            "content-Type": "application/json;odata=verbose"
        },
        data: JSON.stringify(data),
        success: function (data) {
            console.log(data);
        },
        error: function (error) {
            alert(JSON.stringify(error));
        }
    });
}

Here In header, you have to specify the value of X-RequestDigest. It’s a hidden field inside the page.
But some time the “$("#__REQUESTDIGEST").val()” does not work. In that case we need to get it from /_api/contextinfo by sending HTTP POST request to URL (_api/contextinfo)
__metadata is the user comments for update & we can get it by sending GET request to /_api/Web/Lists/getbytitle('List Name')/ListItemEntityTypeFullName
Note: Properties of data are the internal names of the fields. We can get it from following URL by making a HTTP GET request.
var urlForFieldsInternalName = "/_api/Web/Lists/GetByTitle('SpTutorial')/
Fields?$select=Title,InternalName&$filter=ReadOnlyField eq false";

Below are the type of inputs for different field types
Type Value
Single line of text String
Multiple lines of text Multiple lines can be added here also rich text
Choice String but it must come from choices available in the list.
Number Integer or double
Currency Like number
Date and Time String but it must be in ISOString format
Lookup Integer and must be the ID of Lookup item
Yes/No true or false
Person or Group Integer and must be the ID of Person or Group
Hyperlink or Picture Object that has three properties only like __metadata, Url, Description

For multiple person Group type
var data = {
    __metadata: { "type": "SP.Data.TestListItem" },
    Title: "Some title",
    MultiplePersonId: { 'results': [11,22] }
}

Update List item

var updateItemUrl = "/_api/Web/Lists/GetByTitle('SpTutorial')/getItemById('Item Id')";

function updateItem(url, oldItem, newItem) {
    $.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + url,
        type: "PATCH",
        headers: {
            "accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val(),
            "content-Type": "application/json;odata=verbose",
            "X-Http-Method": "PATCH",
            "If-Match": oldItem.__metadata.etag
        },
        data: JSON.stringify(newItem),
        success: function (data) {
            console.log(data);
        },
        error: function (error) {
            alert(JSON.stringify(error));
        }
    });
}

In above HTTP method is PATCH and it is also specified in header ("X-Http-Method": "PATCH") and which is recommended
etag means Entity Tag which is always returned during HTTP GET items which is required while doing any update
Following are the ways to specify etag.
  1. "If-Match": oldItem.__metadata.etag (If etag value does not match, service will return an exception)
  2. "If-Match": "*" (It is considered when force update or delete is needed)
Delete List item

function deleteItem(url, oldItem) {
    $.ajax({
        url: _spPageContextInfo.webAbsoluteUrl + url,
        type: "DELETE",
        headers: {
            "accept": "application/json;odata=verbose",
            "X-RequestDigest": $("#__REQUESTDIGEST").val(),
            "If-Match": oldItem.__metadata.etag
        },
        success: function (data) {
          
        },
        error: function (error) {
            alert(JSON.stringify(error));
        }
    });
}

Here Url is same like we use for updating list item.





)




Ads