SharePoint List REST API. Part 1

Common operations with SharePoint List and Document Library described here: Working with lists and list items with REST. In this post I'll show how to perform operations with most of existing field types such as Metadata (Taxonomy), Multi Choice, Lookup and others.

List Fields

Our demo list contains the following fields:

Demo list fields

Only Title field is required.

Before we begin to work with SharePoint REST API here is a couple of things about environment:

Sample AJAX request:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Accept": "application/json; charset=utf-8",
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val()
    }
});

X-RequestDigest header must contains valid digest for each non-GET REST request (Work with __REQUESTDIGEST).

To get REST url for list you can use this code:


var url = _spPageContextInfo.webServerRelativeUrl + "_api/web/lists/getbytitle('" + listTitle + "')"

List Item EntityType FullName

To interact with data stored in list or document library we have to know the fullname of the entity. To retrieve it from the list you can use following GET-request:


var url = _spPageContextInfo.webServerRelativeUrl + "_api/web/lists/getbytitle('" + listTitle + "')?$select=ListItemEntityTypeFullName"

And the response will contain value what we need:


<?xml version="1.0" encoding="utf-8"?>
<entry>
    <id>https://{YOUR_TENANT_NAME}.sharepoint.com/_api/Web/Lists(guid'{YOUR_LIST_ID}')</id>
    <category term="SP.List" scheme="http://schemas.microsoft.com/ado/2007/08/dataservices/scheme" />
    <link rel="edit" href="Web/Lists(guid'{YOUR_LIST_ID}')" />
    <content type="application/xml">
        <m:properties>
            <d:ListItemEntityTypeFullName>SP.Data.CRUDListListItem</d:ListItemEntityTypeFullName>
        </m:properties>
    </content>
</entry>

In my case entity name equals SP.Data.CRUDListListItem.

So we have all we need to begin: digest from hidden field, list name which we know, web server relative url from _spPageContextInfo object and ListItemEntityTypeFullName property value.

Let's start with the simple and will move step-by-step to complex. In all examples I'll show four operations: Create, Read, Update and Delete.

Single line of text/Multiple lines of text

The simplest case for us definitely is text fields.

Create

To add new item we have to perform POST-request which contains digest:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- digest
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "Title": "TextFieldValue" // <-- "field internal name": "field value"
    })
});

The server response in case of successful completion of the operation will be properties of the newly created item and the status HTTP 201 Created:


<?xml version="1.0" encoding="utf-8"?>
<entry>
    <content type="application/xml">
        <m:properties>
            <d:Id m:type="Edm.Int32">3</d:Id>
            <d:Title>TextFieldValue</d:Title>
        </m:properties>
    </content>
</entry>

Response contains item identity which we will use to retrieve the data.

Read

To read property value we have to know list item ID and internal property name. Request to get the item from server:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)?$select=Title", // <-- list item id
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Update

Update request must contain two special headers: X-HTTP-Method and IF-MATCH:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- list item id
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- digest
        "X-HTTP-Method": "MERGE", // <-- for update request
        "IF-MATCH": "*" // <-- for update request
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "Title": "NewFieldValue" // <-- "field internal name": "field value"
    })
});

Response for update request has status 304 No Content.

All fields must be transfered to Update request?

No, only the fields you need to update. Fields not presented in the request will not be affected.

Delete

Set value to null to clear field value.


$.ajax({
    // rest parameters of the request
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "Title": null // <-- clear field value
    })
});

Choice

Create

There is a choice field in my list and "fill-in" option is disabled:

Choice field

And the first Create request with expected value for the choice field:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- digest
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "SingleChoiceField": "Choice 1" // <-- "field internal name": "field value"
    })
});

And new item in the list:

Please pay attention on the behavior of SharePoint:

Read

See read section for text field.

Update

For update request I try to set not valid value for the choice field:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- list item id
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- digest
        "X-HTTP-Method": "MERGE", // <-- for update request
        "IF-MATCH": "*" // <-- for update request
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "SingleChoiceField": "NotValidValue" // <-- "field internal name": "field value"
    })
});

As you can see validation is up to you in case of using SharePoint REST API:

Delete

See delete section for text field.

MultiChoice

Interaction with text and choice fields is very similar. But in case of multi choice field there are a couple of things to keep in mind.

Create

Multi choice field value unlike single choice must be presented as Collection(Edm.String) object:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- digest
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "MultiChoiceField": {
                "__metadata": {"type": "Collection(Edm.String)"},
                "results": [ // <-- array of values
                        "Choice 1",
                        "Choice 2"
                ]
        }
    })
});

Read

GET-request


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)?$select=MultiChoiceField", // <-- list item id
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

And the response contains array of values:


<?xml version="1.0" encoding="utf-8"?>
<entry>
    <category term="SP.Data.CRUDListListItem" />
    <content type="application/xml">
        <m:properties>
            <d:MultiChoiceField m:type="Collection(Edm.String)">
                <d:element>Choice 1</d:element>
                <d:element>Choice 2</d:element>
            </d:MultiChoiceField>
        </m:properties>
    </content>
</entry>

Update

Another one valid request containing not valid values for multi choice field:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- list item id
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- digest
        "X-HTTP-Method": "MERGE", // <-- for update request
        "IF-MATCH": "*" // <-- for update request
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "MultiChoiceField": {
                "__metadata": {"type": "Collection(Edm.String)"},
                "results": [ // <-- array of values
                        "NotValidValue 1",
                        "NotValidValue 2"
                ]
        }
    })
});

Delete

See delete section for text field.

Single Lookup/User Field

User field is based on lookup field. Therefore both of these field types work similar in REST API context.

Create

Working with lookup field we can pass only identifiers into request. The field name in the request is {FieldInternalName}Id. Just append "Id" after field name:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- digest
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "SingleLookupId": 1 // <-- lookup item ID
    })
});

Read

To retrieve lookup or user field value you can use {LookupFieldName}Id pseudo field to get Id of lookup item. To get full lookup item Id and lookup field you have to pass $expand query parameter:


var restUrl = "/_api/web/lists/getbytitle('CRUDList')/items(3)?"+
    "$select=SingleLookupId,SingleLookup/Id,SingleLookup/Title&"+ // <-- select id and projected fields
    "$expand=SingleLookup"; // <-- expand lookup field
$.ajax({
    url: restUrl,
    type: "GET"
});

And the response for this request:


<?xml version="1.0" encoding="utf-8"?>
<entry>
    <link title="SingleLookup">
        <m:inline>
            <entry>
                <content type="application/xml">
                    <m:properties>
                        <d:Id m:type="Edm.Int32">2</d:Id>
                        <d:Title>Item 2</d:Title>
                    </m:properties>
                </content>
            </entry>
        </m:inline>
    </link>
    <content type="application/xml">
        <m:properties>
            <d:SingleLookupId m:type="Edm.Int32">2</d:SingleLookupId>
        </m:properties>
    </content>
</entry>

Update

Update request is a similar to Create one. Just add item Id and the header values.


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- digest
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "SingleLookupId": 1 // <-- lookup item ID
    })
});

Delete

See delete section for text field.

Multi Lookup/User Field

Multi lookup field in create and update request must be presented as an array of lookup items' identifier.

Name of multi lookup field also must contain Id postfix.

Create

Array of lookup items' identifiers as a value of multi lookup field:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- digest
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- entity type name
        "MultiLookupId": {
                "results": [1, 2, 3]  // <-- lookup item ID
        }
    })
});

Read


var restUrl = "/_api/web/lists/getbytitle('CRUDList')/items(3)?"+
    "$select=MultiLookupId,MultiLookup/Id,MultiLookup/Title&"+ // <-- select id and projected fields
    "$expand=MultiLookup"; // <-- expand lookup field
$.ajax({
    url: restUrl,
    type: "GET"
});

The response contains array of identifiers and array of objects with projected fields:


<?xml version="1.0" encoding="utf-8"?>
<entry>
    <link title="MultiLookup">
        <m:inline>
            <feed>
                <entry>
                    <content type="application/xml">
                        <m:properties>
                            <d:Id m:type="Edm.Int32">1</d:Id>
                            <d:Title>Item 1</d:Title>
                        </m:properties>
                    </content>
                </entry>
                <entry>
                    <content type="application/xml">
                        <m:properties>
                            <d:Id m:type="Edm.Int32">2</d:Id>
                            <d:Title>Item 2</d:Title>
                        </m:properties>
                    </content>
                </entry>
                <entry>
                    <content type="application/xml">
                        <m:properties>
                            <d:Id m:type="Edm.Int32">3</d:Id>
                            <d:Title>Item 3</d:Title>
                        </m:properties>
                    </content>
                </entry>
            </feed>
        </m:inline>
    </link>
    <content type="application/xml">
        <m:properties>
            <d:MultiLookupId m:type="Collection(Edm.Int32)">
                <d:element>1</d:element>
                <d:element>2</d:element>
                <d:element>3</d:element>
            </d:MultiLookupId>
        </m:properties>
    </content>
</entry>

Update

Update request is a similar to Create one for multi lookup field. Just add item Id and the header values.

Delete

See delete section for text field.



The rest of field types such as Metadata, Hyperlink and others will be in the second part of this post.


Share

Comments