Microsoft Graph. Доступ к данным в SharePoint Online

В сентябре 2016 года возможности Microsoft Graph пополнились. Теперь единый endpoint для Office 365 позволяет работать с SharePoint (с сайтами, списками и элементами списков).

В посте пример создания приложения на AngularJS для работы с SharePoint Online.

Что нового

В beta-версию добавили возможность получить информацию о сайтах, списках, элементах. Создавать, обновлять и удалять можно только элементы списка. От общего к частному.

Сайты

Информацию можно только читать. Для этого отправляем GET-запросы. Для получения списка сайтов:

https://graph.microsoft.com/beta/**sharepoint/sites**

GET-запрос для получения информации о сайте:

https://graph.microsoft.com/beta/sharepoint/sites**/{siteCollectionId},{siteId}**

GET-запрос для получения списка дочерних сайтов:

https://graph.microsoft.com/beta/sharepoint/sites/{siteCollectionId},{siteId}**/sites**

Списки

Аналогично GET-запрос для получения списков и библиотек документов сайта:

https://graph.microsoft.com/beta/sharepoint/sites/{siteCollectionId},{siteId}**/lists**

Продолжаем наращивать URL-адрес GET-запроса. Для получения информации о списке:

https://graph.microsoft.com/beta/sharepoint/sites/{siteCollectionId},{siteId}/lists**/{listId}**

Элементы списка

Почти закончили. GET-запрос для получения элементов списка:

https://graph.microsoft.com/beta/sharepoint/sites/{siteCollectionId},{siteId}/lists/{listId}**/items**

Максимальное кол-во элементов, которое будет возвращено - 200. Если элементов в списке/библиотеке больше, то Graph вместе с данными вернет ссылку на следующую страницу:

Для явного указания кол-ва записей, которые необходимо вернуть можно использовать QueryString-параметр $top:

https://graph.microsoft.com/beta/sharepoint/sites/{siteCollectionId},{siteId}/lists/{listId}/items**/?$top=50**

Максимальное количество элементов, которое можно получить - 2147483647 (int.MaxValue).

И последний GET-запрос для получения информации об элементе:

https://graph.microsoft.com/beta/sharepoint/sites/{siteCollectionId},{siteId}/lists/{listId}/items**/{itemId}**

Об элементе списка доступны только его мета-данные:

Для получения данных из полей списка для элементов необходимо указать QueryString-параметр ?expand=columnSet.

Элементы также можно создавать, обновлять и удалять (соответственно запросы POST, PATH и DELETE). Создание элементов происходит аналогично загрузке файлов: сначала создается пустой элемент, потом задание ему свойств, т.е. два запроса к Microsoft Graph.

Немного практики. Аналогично приложения для работы с OneDrive создадим приложение, для просмотра содержимого сайтов в Office 365.

Приложение будет иметь 4 представления:

  • Список корневых сайтов (список коллекций сайтов)
  • Содержимое сайта (дочерние сайты и списки)
  • Просмотр списка (элементы)
  • Просмотр элемента списка

Приложение

Первые три шага идентичны шагам в посте Создаем приложение для OneDrive с помощью AngularJS и Microsoft API. Я их опишу ещё раз, т.к. в новом Azure Portal появилась возможность регистрировать приложения.

Шаг 1. Создаем приложение

Взаимодействовать с Microsoft Graph могут только зарегистрированные в Azure Active Directory (AAD) приложения. Если нет AAD - оформляйте подписку, использование AAD бесплатно. Если приложение ещё создано, то в Azure Portal переходим в раздел Azure Active Directory - Регистрация приложений и нажимаем Добавить:

Указываем Имя, Тип и адрес приложения:

Демонстрационный проект в Visual Studio стартует в режиме отладки по адресу localhost:1323, что я и указал. Копируем Ид приложения, он понадобится нам для работы Azure AD Authentication Library (ADAL):

Шаг 2. Права приложения

Для работы с SharePoint Online понадобятся следующие права:

  • Sites.Read.All
  • Sites.ReadWrite.All

Указываем, что доступ приложению будет предоставлен к Microsoft Graph:

И указываем права:

Шаг 3. Visual Studio

Нового решения я не создавал, а использовал из предыдущего моего примера. Новых файлов всего несколько:

Четыре html-файла в соответствии с необходимыми представлениями, описанными выше:

  • /views/sp.html
  • /views/sp/site.html
  • /views/sp/list.html
  • /views/sp/item.html

Все представления используют один и тот же контроллер (js/controllers/SPController.js) и фабрику (js/services/SPFactory.js). Остальные файлы использовались в предыдущем примере по работе с OneDrive.

Шаг 4. Сервис

Задача сервиса как и раньше - всего лишь сформировать запрос к Microsoft Graph и вернуть его в виде объекта $http:

angular
    .module('MicrosoftGraphSPA')
    .constant('graphBetaUrl', 'https://graph.microsoft.com/beta')
    .factory('spFactory',
    [
        '$http', 'graphBetaUrl',
        function($http, graphBetaUrl) {

            var spFactory = {};

            // Получение списка сайтов
            spFactory.getSites = function(siteId) {
                var url = graphBetaUrl + '/sharepoint/sites';
                if (siteId) {
                    url = url + '/' + siteId + '/sites';
                }
                return $http({
                    method: 'GET',
                    url: url
                });
            };

            // Получение информации о сайте
            spFactory.getSite = function(siteId) {
                return $http({
                    method: 'GET',
                    url: graphBetaUrl + '/sharepoint/sites/' + siteId
                });
            };

            // Получение списков сайта
            spFactory.getLists = function(siteId) {
                return $http({
                    method: 'GET',
                    url: graphBetaUrl + '/sharepoint/sites/' + siteId + '/lists'
                });
            };

            // ...

            return spFactory;
        }
    ]);

Шаг 5. Контроллер

Контроллер единый для всех представлений SharePoint. Параметры текущего представления (идентификаторы сайта, списка, элемента) получаем из $routeParams.

(function () {
    angular
        .module('MicrosoftGraphSPA')
        .controller('SPController', [
            '$scope', '$rootScope', '$http', '$routeParams', 'spFactory',
            function ($scope, $rootScope, $http, $routeParams, spFactory) {
                // Параметры из роутинга
                $scope.siteId = $routeParams.siteId;
                $scope.listId = $routeParams.listId;
                $scope.itemId = $routeParams.itemId;

                $scope.sites = null;
                $scope.lists = null;
                $scope.items = null;
                $scope.item = null;
                $scope.site = null;
                $scope.list = null;

                // Загрузка данных
                $scope.init = function () {

                    // Очищаем результат предыдущего запроса
                    $scope.clearResponse();

                    // Получаем дочерние сайты или корневые
                    spFactory.getSites($scope.siteId).then(
                        function(response) {
                            $scope.sites = response.data.value;
                        },
                        $rootScope.responseError);

                    // Если выбран сайн
                    if ($scope.siteId) {

                        // Получение информации о сайте
                        spFactory.getSite($scope.siteId).then(
                            function (response) {
                                $scope.site = response.data;
                            },
                            $rootScope.responseError);

                        // Получение списков для сайта
                        spFactory.getLists($scope.siteId).then(
                            function(response) {
                                $scope.lists = response.data.value;
                            },
                            $rootScope.responseError);

                        // Если выбран список
                        if ($scope.listId) {

                            // Получение информации о списке
                            spFactory.getList($scope.siteId, $scope.listId).then(
                                function (response) {
                                    $scope.list = response.data;
                                },
                                $rootScope.responseError);

                            //Получение элементов
                            spFactory.getItems($scope.siteId, $scope.listId).then(
                                function(response) {
                                    $scope.items = response.data.value;
                                },
                                $rootScope.responseError);
                        }

                        // Если выбран элемент
                        if ($scope.itemId) {

                            // Получение информации ою элементе
                            spFactory.getItem($scope.siteId, $scope.listId, $scope.itemId).then(
                                function(response) {
                                    $scope.item = response.data;
                                },
                                $rootScope.responseError);
                        }
                    }
                }

                $scope.init();
            }
        ]);
})();

Шаг 6. Роутинг

Роутинг повторяет иерархию в GET-запросах к Microsoft Graph: /sp///.

.when('/sp', { //SharePoint
    templateUrl: 'views/sp.html',
    controller: 'SPController',
    controllerAs: 'controller'
})
.when('/sp/:siteId', { //SharePoint/Site
    templateUrl: 'views/sp/site.html',
    controller: 'SPController',
    controllerAs: 'controller'
})
.when('/sp/:siteId/:listId', { //SharePoint/Site/List
    templateUrl: 'views/sp/list.html',
    controller: 'SPController',
    controllerAs: 'controller'
})
.when('/sp/:siteId/:listId/:itemId', { //SharePoint/Site/List/Item
    templateUrl: 'views/sp/item.html',
    controller: 'SPController',
    controllerAs: 'controller'
})

Шаг 7. Интерфейс

Интерфейсы все крайне просты. Для примера приведу только представление для просмотра информации об элементе:

<!-- Breadcrumb -->
<ul class="breadcrumb">
    <li><a href="#/">Microsoft Graph SPA</a></li>
    <li><a href="#/onedrive">OneDrive</a></li>
    <li><a href="#/sp/{{siteId}}">{{site.name!=''?site.name:'Root'}}</a></li>
    <li><a href="#/sp/{{siteId}}/{{listId}}">{{list.name}}</a></li>
    <li class="active">{{item.columnSet.Title}}</li>
</ul>

<div class="row">
    <table class="table table-striped table-bordered table-hover table-condensed">
        <thead>
            <tr>
                <th>Property</th>
                <th>Value</th>
            </tr>
        </thead>
        <tbody>
        <!-- Перебираем все поля и выводим значения -->
        <tr ng-repeat="(key, value) in item.columnSet">
            <td>{{ key }}</td>
            <td>{{ value }}</td>
        </tr>
        </tbody>
    </table>
</div>

Просмотр свойств элемента списка в браузере:

Всё приложения для просмотра содержимого SharePoint Online занимает примерно 330 строчек (HTML+JS), без учета Bootstrap, jQeury, AngularJS, ADAL.

Исходные коды

Исходные коды приложения доступны на MSDN Samples.

Смотрите также

Создаем приложение для OneDrive с помощью AngularJS и Microsoft API

Microsoft Graph. Подключение к данным

Виталий Жуков

Виталий Жуков

SharePoint архитектор, разработчик, тренер, Microsoft MVP (Office Development). Более 15 лет опыта работы с SharePoint, Dynamics CRM, Office 365, и другими продуктами и сервисами Microsoft.

Смотрите также

Создаем приложение для OneDrive с помощью AngularJS и Microsoft API

Создаем приложение для OneDrive с помощью AngularJS и Microsoft API

Презентация с доклада о Microsoft API и Office Graph

Презентация с доклада о Microsoft API и Office Graph

Microsoft Graph. Подключение к данным

Microsoft Graph. Подключение к данным