SharePoint List REST API. Часть 1

Основные операции по работе со списками и библиотеками документов описаны в статье Работа со списками и элементами списков с использованием REST. В этом посте я покажу как выполнять операции с большинством из существующих типов полей, таких как метаданные (Таксономия), множественный выбор, подстановка и другими.

Поля списка

Мой демонстрационный список содержит следующие поля:

Поля демонстрационного списка

Обязательным является только поле Title.

Перед тем как мы начнем работать с SharePoint REST API пара моментов о среде:

Простой AJAX запрос:


$.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 должен содержать допустимое значение дайджеста для каждого не-POST запроса (Работа с __REQUESTDIGEST).

Для получения REST url'а для списка можно использовать следующий код:


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

List Item EntityType FullName

Для взаимодействия с данными, хранящимися в списке или библиотеке документов мы должны знать полное имя сущности. Получить это имя можно из соответствующего списка с помощью GET-запроса:


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

Ответ от сервера будет содержать нужное нам значение:


<?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>

В моём случае имя сущности - SP.Data.CRUDListListItem.

Итак, у нас есть всё необходимое, чтобы начать: дайджест из скрытого поля страницы, имя списка, которое нам известно, относительный url сайта из объекта _spPageContextInfo и значение свойстваListItemEntityTypeFullName нашего списка.

Начнем с простого и будем постепенно переходить к сложному. Во всех примерах я покажу как выполнять четыре операции: Создание, Чтение, Обновление и Удаление.

Текст

Самый простой пример использования REST API.

Создание

Чтобы добавить новый элемент списка мы должны выполнить POST-запрос:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "Title": "TextFieldValue" // <-- "Имя поля": "Значение"
    })
});

Ответ от сервера в случае успешного завершения операции будет содержать свойства созданного элемента и статус запроса будет 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>

Ответ содержит также идентификатор элемента, который можно использовать для чтения данных.

Чтение

Чтобы получить значение свойства, мы должны знать идентификатор элемента и внутреннее имя поля. Запрос на чтение данных:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)?$select=Title", // <-- Идентификатор элемента 
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Обновление

Запрос на обновление должен содержать два дополнительных заголовка: X-HTTP-Method и IF-MATCH:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- lsit item id
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- дайджест
        "X-HTTP-Method": "MERGE", // <--  заголовки для запроса на обновление
        "IF-MATCH": "*" // <--  заголовки для запроса на обновление
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "Title": "NewFieldValue" // <-- "Имя поля": "Значение"
    })
});

Ответ на запрос обновления имеет статус 304 No Content (если всё прошло хорошо).

Значения всех полей необходимо передавать?

Нет, только те поля и значения, которые необходимо обновить. Поля не представленные в запросе обновлены не будут.

Удаление

Просто укажите значение поля равным null чтобы удалить его содержимое.


$.ajax({
    // другие параметры запроса
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "Title": null // <-- удаляем значение поля
    })
});

Выбор

Создание

В моём списке есть одно поле выбора и запретом на добавление новых значений при вводе данных:

Choice field

Первый запрос на создание элемента с ожидаемым значением поля выбор:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleChoiceField": "Choice 1" // <-- "Имя поля": "Значение"
    })
});

И новый элемент в списке:

Обратите внимание на поведение SharePoint:

Чтение

Смотрите раздел чтение для текстовых полей.

Обновление

Для запроса на обновление я пробую казать невалидные значения для значения поля:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- Идентификатор элемента
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- дайджест
        "X-HTTP-Method": "MERGE", // <-- for update request
        "IF-MATCH": "*" // <-- заголовки для запроса на обновление
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleChoiceField": "NotValidValue" // <-- "Имя поля": "Значение"
    })
});

Как видно, за валидацией надо следить самому при использовании SharePoint REST API:

Удаление

Смотрите раздел read для текстовых полей.

Множественный выбор

Работа с текстовыми полями и полем выбора (единственного) идентична. Но в случае множественного выбора есть несколько важных моментов, о которых надо помнить.

Создание

Значение поля множественного выбора должно быть представлено объектом Collection(Edm.String):


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "MultiChoiceField": {
                "__metadata": {"type": "Collection(Edm.String)"},
                "results": [ // <-- array of values
                        "Choice 1",
                        "Choice 2"
                ]
        }
    })
});

Чтение

GET-запрос


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)?$select=MultiChoiceField", // <-- Идентификатор элемента
    type: "GET",
    headers: {
        "Content-Type": "application/json;odata=verbose"
    }
});

Ответ от сервера содержит массив значений:


<?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>

Обновление

Ещё один правильный запрос с неправильными значениями в поле множественного выбора:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items(3)", // <-- Идентификатор элемента
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val(), // <-- дайджест
        "X-HTTP-Method": "MERGE", // <--  заголовки для запроса на обновление
        "IF-MATCH": "*" // <--  заголовки для запроса на обновление
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "MultiChoiceField": {
                "__metadata": {"type": "Collection(Edm.String)"},
                "results": [ // <-- массив значений
                        "NotValidValue 1",
                        "NotValidValue 2"
                ]
        }
    })
});

Удаление

Смотрите раздел чтение для текстовых полей.

Единственная подстановка/Пользователь

Поле выбора пользователя унаследовано от поля подстановки. Поэтому работа с обеими этими типами полей работа идентична в REST API.

Создание

В случае подстановки/пользователя достаточно передать только идентификатор элемента. Имя поля в запросе должно иметь вид {FieldInternalName}Id. Просто добавьте "Id" к имени поля:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleLookupId": 1 // <-- Идентификатор элемента подстановки
    })
});

Чтение

Для чтения значения из поля подстановки можно использовать псевдо-поле {LookupFieldName}Id для получения идентификатор элемента. Для получения полного набора идентификатора и текстового поля элемента необходимо указывать само поле в параметре $expand запроса:


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"
});

Ответ на запрос от сервера:


<?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>

Обновление

Запрос на обновление идентичен запросу на создание. Просто добавьте идентификатор обновляемого элемента и необходимые заголовки запроса.


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "SingleLookupId": 1 // <-- Идентификатор элемента подстановки
    })
});

Удаление

Смотрите раздел удаление для текстовых полей.

Множественная подстановка/Пользователи

Поле множественного выбора в запросах создания и обновления должно быть представлено массивом идентификаторов.

Имя поля множественной подстановки также должно содержать постфикс Id.

Create

Массив идентификаторов элементов подстановки в качестве значения поля:


$.ajax({
    url: "/_api/web/lists/getbytitle('CRUDList')/items",
    type: "POST",
    headers: {
        "Content-Type": "application/json;odata=verbose",
        "X-RequestDigest": $("#__REQUESTDIGEST").val() // <-- дайджест
    },
    data: JSON.stringify({
        "__metadata": { "type": "SP.Data.CRUDListListItem" }, // <-- имя сущности
        "MultiLookupId": {
                "results": [1, 2, 3]  // <-- Идентификатор элемента подстановки
        }
    })
});

Чтение


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"
});

Ответ от сервера содержит массив идентификаторов и коллекцию объектов с выбранными полями:


<?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>

Обновление

Запрос на обновление идентичен запросу на создание. Просто добавьте идентификатор обновляемого элемента и необходимые заголовки запроса.

Удаление

Смотрите раздел удаление для текстовых полей.



Работа с другими типами полей такими как метаданные, ссылка и другими я покажу во второй части этого поста.


Поделиться

Коментарии