Open protocol что это

Обновлено: 07.07.2024

Что нового в WCF Data Services?

Одним из наиболее частых пожеланий, высказывавшихся заказчиками после первого выпуска, было введение возможности запрашивать количество сущностей в наборе. И новый механизм «счетчика» как раз для этого и включен. Он состоит из двух частей. Во-первых, он позволяет запрашивать только счетчик, т. е. количество значений, которое должен вернуть запрос. Во-вторых, добавлен параметр запроса, который сообщает сервису включать счетчик общего количества сущностей в набор, когда результатом запроса является частичный набор, например при включенной поддержке разбиения набора на страницы на серверной стороне (server paging).

Чтобы упростить связывание с данными от OData-сервиса, в клиентскую библиотеку WCF Data Services добавлен новый тип — DataServiceCollection. Он реализует отслеживание изменений содержащихся в нем элементов (через интерфейсы INotifyPropertyChanged и INotifyCollectionChanged). Если его привязать к какому-либо элементу управления (например, DataGrid в Silverlight), он будет отслеживать изменения, внесенные в объекты и в сам набор. Этот новый набор значительно облегчает процесс создания OData-клиентов.

Чтобы помочь вам понять ценность экосистемы OData, мы создадим веб-приложение — сайт вымышленной риэлтерской компании Contoso Ltd., где посетители смогут просматривать лоты управляемой ею недвижимости.

Другие провайдеры данных OData

До сих я показывал примеры использования данных от SQL Server, SharePoint и универсального OData-сервиса в Интернете, но существуют и другие варианты. Облачная платформа Windows Azure имеет сервис таблиц, которые предоставляет доступ к данным, хранящимся в таблицах Windows Azure, и соответствующий API построен на использовании OData. Как упоминалось, проект Microsoft Dallas является централизованной площадкой для поиска и запроса данных, предоставляемых сервисом Dallas, и этот сервис обеспечивает доступ к своим данным по протоколу OData. Кроме того, провайдеры данных OData не ограничены только продуктами Microsoft; в частности, IBM недавно объявила, что ее продукт WebSphere eXtreme Scale 7.0 теперь поддерживает протокол OData.

Соглашения в OData по URI

Синтаксис URI также определяет количество параметров запроса, которые можно добавлять в конец URI для модификации базового запроса, а каждый параметр запроса определяется как пара «имя-значение». Например, добавив параметр запроса $top=10, вы ограничите результат запроса только первыми десятью элементами. На рис. 1 перечислены все параметры запросов, доступные в этом синтаксисе URI.

Рис. 1. Параметры OData-запроса

$top=n Ограничивает запрос первыми n сущностями
$skip=n Пропускает первые n сущностей в наборе
$inlinecount=allpages Включает счетчик всех сущностей из набора в результат
$filter=<выражение> Выражение позволяет ограничивать результаты, возвращаемые запросом (пример: $filter=Status eq 'Available' ограничивает результаты сущностями, у которых свойство Status имеет значение "Available").
$orderby=<выражение> Упорядочивает результаты по набору свойств сущности
$select=<выражение> Указывает возвращаемое подмножество свойств сущности
$format Указывает формат возвращаемого канала (ATOM или JSON). Этот параметр не поддерживается в WCF Data Services

OpenID Connect простыми словами

Некоторое время назад я получил довольно непростую задачу написать техническое задание для нашей службы поддержки на тему OpenID Connect (OIDC).

Тут же я понял, что хоть я и знаком с OAuth и SAML, я не знал практически ничего об OpenID Connect (кроме того, что благодаря этому Pokemon Go получает сведения о моем профиле сразу после авторизации в Google+).

К счастью, мои коллеги подробно посвятили меня во все детали и снабдили необходимыми ресурсами для ознакомления. Хотя, честно говоря, ни одно из объяснений не показалось мне достаточно хорошим и качественным. Поэтому представляю моё видение данного процесса.

Основы OIDC

Если просто, то OIDC — это безопасный механизм, позволяющий приложению связаться со службой идентификации, чтобы получить необходимые данные о пользователе и вернуть их обратно в приложение, обеспечив полную защиту данных.

По своей сути, OpenID Connect начинал свой путь как механизм авторизации OAuth "любительского уровня" или, если говорить более высокопарно, "механизм, предоставляющей пользователю возможность создать единую учетную запись для аутентификации на множестве не связанных друг с другом интернет-ресурсов".

Каждый, кто хоть раз участвовал в викторине "Кто ты из…?" на Facebook, уже имел шанс ознакомиться с процессами OAuth в действии: сначала нужно авторизоваться в системе управления доступами (в данном случае — Facebook), а затем дать права на использование персональных данных с вашей страницы.


Важно отметить, что такие права называются scopes — области видимости. Для OIDC существует особая область видимости openid, которую необходимо использовать в качестве первого обращения к системе управления доступами.

Сразу после того, как мы разобрались со scopes, возникает следующий резонный вопрос: “Как работать с OpenID?”.

Познакомимся с флоу работы с OpenID

Порядок работы с OpenID connect во многом зависит от типа клиента, который вы используете и от того, насколько хорошо он умеет хранить секреты.

Например, если вы используете приложение JavaScript, где всё и вся может просматриваться любым, кто использует инструменты-разработчики браузера, а также отсутствует бэкенд-механизм, чтобы скрыть информацию от любопытных глаз пользователей — на помощь придет Implicit Flow для OpenID Connect.

Если же вы пользуетесь более традиционными приложениями, где какая-то информация передается на фронтенд (и есть вероятность, что кто-то может ее перехватить), но в то же время используется бэкенд, чтобы передавать информацию службе управления доступами абсолютно конфиденциально, используйте Authentication Flow.

Также существует Hybrid Flow, который является сочетанием двух вышеупомянутых методов.

A. Implicit Flow

Этот флоу разработан для передачи основной информации о пользователе приложению. И на этом всё.
Хотя нет…


В спецификации OIDC обращается особое внимание, что запрашиваемая информация о пользователе должна быть упакована в JWT (JSON токен), зашифрована или подписана. Более того, информация об этих шагах (как и когда упакована/зашифрована/подписана) должна быть включена в набор данных, отправляемых обратно.

В конечном счете, требования к Implicit flow таковы: он должен использовать схему открытого / закрытого ключа для шифрования или подписи информации о пользователе, а также содержать в полной конфиденциальности client_secret.

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

B. Authentication Flow


Данный флоу разработан, чтобы функционировать как стандартный three-legged OAuth. В итоге обычный токен доступа OAuth секретным образом возвращается в веб-приложение через вызовы, сделанные на серверной части.

В таком флоу вместо передачи данных о пользователе, служба управления доступами отправляет специальный одноразовый пароль, который можно обменять на токен доступа OAuth через бэкенд сервис. Такой обмен должен включать client_id и client_secret в дополнение к коду, также, как и в стандартном флоу OAuth.

Затем токен доступа OAuth должен быть использован веб-сервисом для подтверждения подлинности, а также для запроса разного рода информации о пользователе (это определяется запрошенными типами scopes и claims).

Сейчас, в мире, где существуют разнообразные службы управления доступами, такие claims обычно предварительно утверждаются администратором, отвечающим за настройку приложения, но на любительском уровне (где непосредственно конечный пользователь подтверждает доступ к приложению) они выступают в виде запросов на разрешение (scopes) во время изначального application flow.

OIDC определяет целый ряд claims, и некоторые из них имеют довольно узкое определение (например, только email адрес пользователя), в то время, как другие являются довольно обширными и могут возвращать любую запрошенную информацию системе управления доступами (такую, как, например, информация о профиле пользователя).

В дополнение, хочется отметить, что cистемы OIDC также предоставляют refresh-токен (если веб-сервису необходим более длительный доступ к информации о пользователе), так же, как и персонализированные claims.

C. Hybrid Flow

Данный флоу сочетает в себе характеристики двух вышеупомянутых типов с одним небольшим преимуществом: такой флоу позволяет передавать токен доступа напрямую клиенту.

Общепринятым считается, что front channel токен не настолько безопасен, как, например, back channel токен, поэтому иногда их срок службы короче и может быть увеличен за счет back-channel вызовов.

Общеизвестный endpoint

Вы, вероятно, уже заметили, что клиенту нужно владеть немалым объемом информации, чтобы правильно выполнять различные рукопожатия OIDC и обмениваться информацией. Плюс ко всему, немаловажным является вопрос куда он должен обратиться чтобы получить ключи доступа, используемые для подписи или шифрования этой информации.

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

jwks_uri — это URL, к которому клиент может получить доступ для получения информации о любых ключах JWK, используемых Google, в формате, установленном спецификацией OIDC.

Одно из значений, возвращаемых для каждого ключа, — это ключевой id (kid), который можно использовать для того, чтобы определить, изменился ли криптографический ключ.

Проще говоря, проверив этот показатель/значение, клиент может определить, изменился ли открытый ключ у системы управления доступом с момента его последнего использования, и автоматически обновиться, чтобы использовать эту информацию.

Посмотрите, к примеру, на SAML. По этой логике здесь работает автоматическая ротация ключей (automatic key rotation).

Заключение

В этом обзоре я постарался простым языком рассказать про азы и основные моменты каждого из флоу. Вместе с тем, гораздо более умные ребята, чем я, уже давно выпустили официальные спецификации со всеми подробностями. Я настоятельно рекомендую вам ознакомиться с ними перед началом работы.

Также сообщество разработчиков OpenID проделало огромную работу и разработало множество классных инструментов, которые помогут вам сделать первые шаги и начать экспериментировать.

И наконец, OIDC — это стандарт. На его основе уже разработано большое количество OIDC-клиентов. Возможно, в вашем случае даже не потребуется создавать свой. Главное, теперь, когда у вас есть понимание основных типов флоу и их применимости — убедитесь, что вы выбрали подходящий тип для вашего конкретного случая!

Реляционные данные

После создания и настройки веб-сервиса мы создадим модель данных Entity Framework, которую будет предоставлять канал OData. Visual Studio упрощает эту задачу с помощью мастера Add New Item, позволяющего автоматически генерировать такую модель на основе существующей базы данных. На рис. 1 показана простая модель данных, созданная с применением мастера Add New Item поверх данных SQL Server, в которых содержатся сведения о недвижимости и лотах, управляемых Contoso.

image: The Entity Framework Data Model for the Relational Data


Рис. 1. Модель данных Entity Framework для реляционных данных

Теперь создадим WCF-сервис данных, открывающий доступ к этой модели как к каналу OData. Visual Studio позволяет упростить и эту задачу выбором варианта WCF Data Service в мастере Add New Item. В этом случае Visual Studio предоставляет файл кода (в данном примере этот файл называется Listings.svc.cs), используемый для конфигурирования сервиса данных.

Рис. 2. Определение WCF-сервиса данных

Давайте подробнее рассмотрим, что еще делает метод InitalizeService на рис. 2. Он вызывает SetEntitySetAccessRule для обоих наборов сущностей, которые будет предоставлять сервис и задает права доступа как AllRead. Это указывает сервису сделать оба набора сущностей полностью доступными для чтения, но запретить любые попытки вставок, обновлений или удалений. И это отличный способ управлять доступом к сервису. WCF Data Services также поддерживает методы, называемые перехватчиками запросов (Query Interceptors); они позволяют автору сервиса более тонко разграничивать права доступа для сервиса индивидуально для каждого набора сущностей. Установите файл Listings.svc как стартовую страницу проекта и запустите проект. Откроется окно браузера, и вы увидите документ сервиса (рис. 3).

image: Service Document for the SharePoint Site


Рис. 3. Документ сервиса для сайта SharePoint

Экосистема OData

В этой статье я ознакомлю вас с несколькими продуктами, инфраструктурами и веб-сервисами, которые используют или создают каналы OData. Этот протокол определяет ресурсы, методы и операции (GET, PUT, POST, MERGE и DELETE, соответствующие операциям чтения, создания, замены, слияния и удаления), которые можно выполнять применительно к этим ресурсам с помощью методов.

На практике это означает, что любой клиент, способный работать с протоколом OData, может выполнять операции с любым источником данных. Для программирования клиента, использующего некий сервис, вовсе не обязательно знать модель программирования этого сервиса — достаточно выбрать целевой язык для работы с ним.

Перспективная цель OData — создание клиентской библиотеки OData для всех основных технологий, языков программирования и платформ, чтобы любое клиентское приложение могло задействовать все богатства каналов OData. Источники и потребители OData образуют «экосистему» OData.

Использование справочных данных от OGDI

По умолчанию канал OData будет возвращать ATOM-представление, поэтому при обращении из браузера результат будет показываться как канал ATOM. Если в запросе изменить заголовок приема (accept header) на «application/json», те же данные будут возвращаться как канал JSON.

Канал на рис. 5 начинается с элемента <feed>, представляющего набор сущностей. Внутри каждого канала содержится набор элементов <entry>, каждый из которых представляет одну сущность в канале (первые три элемента <entry> свернуты, чтобы на экране было видно содержимое всего канала).

В этом примере для сущности определен маркер параллельной обработки (concurrency token); в итоге у каждой сущности в этом канале есть свойство etag. Это свойство — маркер, используемый сервисом данных для принудительной проверки на параллельную обработку, когда в запрошенную сущность вносится какое-либо изменение. Каждая сущность, отформатированная с применением тега <entry>, состоит из набора ссылок, который содержит как ссылку для использования при редактировании сущности, так и отношения с другими сущностями. Каждая ссылка отношения (relationship link) указывает либо на другую сущность, либо на набор сущностей (такие свойства называют соответственно ссылочными и навигационными). Каждый элемент <entry> также включает элемент <m:properties>, содержащий свойства сущности элементарного и комплексного типов; значения свойств состоят из имени свойства сущности и значения самого свойства.

Как уже говорилось, веб-сайт OGDI содержит общедоступные сведения о Вашингтоне, округ Колумбия. Приложение Contoso для управления недвижимостью применяется для просмотра лотов в этом округе, и пользователям было бы очень полезно получать эти открытые справочные сведения о местности вокруг конкретного дома. Создавая клиент для этого приложения-примера, я продемонстрирую, как включить канал OData с веб-сайта OGDI в качестве одного из источников данных для приложения.

В статье рассматриваются:

  • проблемы доступа к данным, хранящихся на разных платформах и устройствах;
  • OData и его экосистема;
  • Windows Phone 7 OData Library;
  • поддержка LINQ;
  • замораживание (tombstoning) в Windows Phone 7;
  • передача удостоверений OData-сервису.

В этой статье я расскажу о серьезной проблеме с доступом к данным, с которой, на мой взгляд, сталкиваются сегодня во многих организациях, а затем покажу, как Open Data Protocol (OData) и его экосистема способны помочь в решении этой проблемы. Далее мы рассмотрим, как с помощью OData создавать удобные в использовании приложения для Windows Phone 7, применяя новую библиотеку OData для бета-версии Windows Phone 7.1 (кодовое название «Mango»).

Управление данными с помощью протокола OData

OData является одним из лучших стандартов для создания RESTful API.


OData позволяет задавать огромное число параметров, которые позволяют сформировать очень сложные запросы к источнику данных, например:

Язык запросов OData сопоставим по мощности с SQL.

Базовые возможности OData
  • Простое чтение данных (запросы без параметров)
    • Получение коллекции объектов
    • Получение отдельного объекта
    • Получение отдельного свойства
    • Получение объектов по связям. Например, получение списка друзей друзей.
    • Поиск по критериям (“меньше”, ”больше” и т.п.), возможность построения сложных условий, используя логические выражения.
    • Поиск по связям (по связанным объектам)
    • Сортировка по любому набору полей
    • Получение составных сложных объектов, например, получить данные о человеке вместе с его телефонами и списком друзей
    • Пэйджинг
    • Добавление простых объектов
    • Добавление коллекций объектов
    • Добавление составных объектов (вместе с вложенными объектами)
    • Модификация отдельных свойств (полей)
    • Замена объекта целиком на новый
    • Удаление объектов
    • Удаление коллекций
    • Удаление отдельных свойств (полей)
    Библиотеки для работы с OData

    Многие из этих библиотек существенно упрощают разработку сложных приложений благодаря стандарту OData. Например, достаточно грид контролу указать URL к серверу OData и все остальное он сделает сам: пэйджинг, сортировку, добавление- модификацию-удаление записей, фильтрацию данных, группировку и т.д.

    Open Data Protocol

    Замораживание

    Приложение Windows Phone 7 иногда получает от ОС уведомление о необходимости деактивации, чтобы ОС могла активировать другое приложение. Это может произойти, например, если пользователь нажимает кнопку Home на смартфоне или получает входящий вызов. В бета-версии Mango приложение не всегда деактивируется в таких случаях благодаря тому, что функция быстрого переключения приложений зачастую позволяет ОС переключаться на другое приложение без предварительной деактивации текущего. Когда ОС сообщает приложению о необходимости деактивации, это приложение может сохранить свое текущее состояние локально, чтобы при последующей активации — а это возможно при нажатии пользователем кнопки Back, например, — оно восстановило свое предыдущее состояние и пользователь мог продолжить работу с ним, прерванную из-за деактивации. Этот процесс называют замораживанием (tombstoning). Он особенно полезен в приложении, использующем данные из внешнего источника данных, так как замораживание избавляет приложение от необходимости повторной загрузки данных по сети из внешнего источника.

    Замораживание в Windows Phone 7 осуществляется сериализацией состояния приложения в набор строк в словаре. В клиентской библиотеке OData для Windows Phone 7 есть вспомогательные средства для сериализации текущего состояния — это методы, способные сериализовать или десериализовать DataServiceContext и набор объектов DataServiceCollection. В коде на рис. 7 показан пример использования этих методов для формирования строки, представляющей текущее состояние. Приложения Windows Phone 7 должны реализовать методы Application_Activated и Application_Deactivated, через которые ОС указывает приложению о необходимости его активации или деактивации. Из этих методов можно вызывать методы Serialize и Deserialize в DataServiceContext.

    Рис. 7. Сериализация и десериализация DataServiceContext

    Удостоверения

    OData в PowerPivot

    image: PowerPivot Imports from an OData Feed


    Рис. 11. PowerPivot импортирует данные из канала OData

    На рис. 12 показана сводная диаграмма по статистике криминогенной обстановки в Вашингтоне, округ Колумбия, полученной от OGDI.

    image: PowerPivot Chart from OData Feed


    Рис. 12. Диаграмма PowerPivot на основе информации из канала OData

    Продукты и технологии:

    Предоставление данных из SharePoint

    В предыдущем разделе я показал, как обеспечить доступ к данным, хранящимся в моей реляционной базе данных с информацией о недвижимости и лотах для веб-сайта риэлтерской компании. Допустим, у меня есть также информация об агентах по продажам недвижимости, но эти сведения хранятся на сайте SharePoint. Microsoft SharePoint 2010 позволяет предоставлять все списки и документы внутри этих списков как канал OData. Это просто замечательно для сайта риэлтерской компании, так как информация об агентах, введенная сотрудниками компании, доступна по каналу OData, который может быть включен в создаваемое мной приложение для обработки лотов (Listings application). Компаниям, у которых есть процессы ввода и обновления таких данных через интерфейс SharePoint, не придется что-либо менять в своих рабочих процессах для подстройки под мое приложение. Данные, введенные на сайт SharePoint компании, доступны в реальном времени для создаваемого приложения Listings.

    На рис. 5 показан простой портал SharePoint, используемый агентами по продаже недвижимости для записи и обновления своей контактной информации.

    image: SharePoint Site for Agent Information


    Рис. 5. Сайт SharePoint для хранения информации об агентах

    image: Agents Feed from the SharePoint Agent Service


    Рис. 6. Канал агентов для SharePoint Agent Service

    Клиент Silverlight

    В Silverlight 3 клиентская библиотека WCF Data Services включается в Silverlight SDK, который упрощает взаимодействие приложений Silverlight с сервисом, поддерживающим OData. Для этого в Visual Studio из проекта Silverlight щелкните правой кнопкой мыши проект и выберите Add Service Reference. В итоге это позволит добавить ссылку на сервис. Главное, что вы должны ввести, — URI сервиса, на который есть ссылка из приложения Silverlight. На рис. 7 показан пример добавления ссылки на сервис-пример OGDI.

    image: Add Service Reference for the OGDI Sample Service


    Рис. 7. Добавление ссылки на сервис-пример OGDI

    На рис. 8 приведен внешний вид приложения Home Finder на Silverlight. Оно будет размещено в SharePoint, чтобы к нему могли легко обращаться мои существующие пользователи, привыкшие работать в среде SharePoint.

    image: The Contoso Home Finder


    Рис. 8. Contoso Home Finder

    На рис. 9 представлен код для запроса сервиса Listings и связывания результата с элементом управления «сетка» в верхней части окна приложения Home Finder.

    Рис. 9. Создание контекстов клиентских прокси

    Код на рис. 9 создает DataServiceCollection — отслеживаемый набор — и привязывает его к свойству ItemsSource основной сетки лотов. Поскольку этот набор реализует отслеживание изменений, любое изменение, внесенное в элементы сетки, будет автоматически отражаться на сущностях в наборе лотов. Изменения, внесенные в сетке, можно сохранять в сервисе вызовом метода BeginSaveChanges контекста для сервиса Listings.

    В Silverlight все сетевые вызовы осуществляются асинхронно, поэтому выполнение любых операций с сервисом с применением клиентской библиотеки WCF Data Services требует начального вызова операции и написания отдельного метода обратного вызова, передаваемого для последующей обработки результата асинхронного вызова. Чтобы упростить работу с асинхронными вызовами, в класс DataServiceCollection был добавлен метод LoadAsync, который берет на себя выполнение всей работы с функцией обратного вызова и загрузки результатов в набор.

    В коде на рис. 8 набор связывается с сеткой до вызова LoadAsync, и значения не загружаются в набор, пока не завершится асинхронный вызов. Набор будет генерировать события изменения набора при возврате результатов сервисом; сетка будет захватывать эти события и отображать результаты по завершении асинхронного вызова.

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

    На рис. 9 показано, как запросить у сервиса SharePoint сущность агента, передав ему имя агента. Похожий код используется для запроса от OGDI статистических данных по криминогенной обстановке в близлежащей местности на диаграмме внизу страницы Home Finder. Код вплоть до этого момента демонстрирует только возможности запросов клиента Silverlight, но такой клиент не ограничен одними запросами; он располагает богатыми средствами для обратной записи изменений в сервис.

    Рис. 10. Выполнение асинхронного запроса

    Поддержка LINQ

    Рис. 4. Выполнение LINQ-запроса

    Если вы уже использовали инструмент Add Service Reference, контекст клиентского прокси, поддерживающий создание LINQ-запросов, будет сгенерирован автоматически.

    Библиотека OData включает специфичный для OData тип набора, DataServiceCollection<T>, который реализует INotifyCollectionChanged. Если для хранения сущностей в клиенте применяется DataServiceCollection, эти сущности можно связывать с UI-элементами в XAML и автоматически отслеживать изменения в них. Любые обновления в таких сущностях могут быть переданы сервису вызовом SaveChanges в клиентском контексте. На рис. 6 показана базовая XAML-привязка с применением класса DataServiceCollection — прокси-классы, сгенерированные с помощью инструментария, реализуют INotifyPropertyChanged и отражают изменения, внесенные через UI.

    Рис. 6. XAML-привязка

    Если вы собираетесь вручную отслеживать изменения, то можете отказаться от использования DataServiceCollection в генерации кода. Это может немного повысить производительность вашего приложения, так как в этом случае не будут генерироваться уведомляющие события.

    Процесс выполнения запроса к сервису OData и получения результатов включает вызов сетевого стека Windows Phone 7, который всегда должен быть асинхронным. Методы в DataServiceContext, BeginExecute и EndExecute асинхронно выполняют запрос к сервису, используя шаблон IAsyncResult. Этот шаблон иногда утомителен в использовании, поэтому метод LoadAsync в DataServiceCollection скрывает большую часть деталей асинхронного выполнения. Этот же метод асинхронно добавит результат запроса в DataServiceCollection и сгенерирует события INotifyCollectionChanged для UI-элементов, чтобы они соответственно изменили свое содержимое. В наборе также есть событие LoadCompleted; если вы на него подпишетесь, то оно будет вызываться, когда загрузка данных осуществляется асинхронно.

    Проблема доступа к данным

    Интересная вещь произошла в конце 2010 года: впервые объем поставок смартфонов превысил объем поставок ПК. Здесь нужно отметить ключевой момент: это не состязания, исход которых предопределен. На рынке много игроков (Apple Inc., Google Inc., Microsoft, Research In Motion Ltd. и др.) и платформ (настольных, Web, смартфонов, планшетных компьютеров и часто появляющихся устройств новых типов). Во многих организациях нужно, чтобы клиентские приложения работали на всех или на большинстве этих устройств. И во многих организациях есть большие объемы данных, а также сервисы, которые они хотели бы сделать доступными для клиентских устройств. Сервисы могут работать на предприятии и доступными через традиционные веб-сервисы или же они могут быть созданы в облаке.

    Постоянно увеличивающееся разнообразие клиентских платформ с не менее разнообразными сервисами приводит к значительным расходам и сложностям при использовании данных и сервисов. При добавлении поддержки новой клиентской платформы данные и сервисы зачастую приходится обновлять и модифицировать. А когда добавляется новый сервис, нужно модифицировать существующие клиентские платформы для поддержки этого сервиса. Это и есть то, что я называю проблемой доступа к данным (data reach problem). Как определить сервис, достаточно гибкий, чтобы удовлетворять потребностям не только всех существующих клиентских устройств, но и новых, пока еще не изобретенных? Как определить клиентские библиотеки и приложения, способные работать с разнообразными сервисами и источниками данных? Это лишь некоторые из ключевых вопросов, на которые, как я надеюсь, можно хотя бы частично ответить с помощью OData.

    Где узнать больше

    Выражаю благодарность за рецензирование статьи эксперту Гленну Гейли (Glenn Gailey).

    Экосистема OData

    рис. 1. Некоторые компоненты экосистемы OData

    В целом, я могу ориентироваться на любой сервис, перечисленный в рис. 1, и использовать любой клиент. Чтобы продемонстрировать это на практике, я дам ряд примеров использования OData с несколькими разными клиентами.

    Сервис Northwind


    Рис. 2. Сервис Northwind

    Рассмотрим несколько примеров применения клиентских библиотек для использования и создания функциональности доступа к данным через OData-сервис Northwind. В первом примере будем считать, что клиентская функциональность не требует написания какого-либо кода. Надстройка PowerPivot для Excel предоставляет механизм анализа данных в памяти, который можно напрямую использовать из Excel, и поддерживает импорт данных непосредственно из канала OData. Надстройка PowerPivot также поддерживает прямой импорт данных из Microsoft Azure Marketplace DataMarket и ряда других источников данных.

    На рис. 3 приведена сводная диаграмма, созданная импортом данных Products и Orders из OData-сервиса Northwind и объединением результатов. Поля цены за единицу и количества в позициях заказа скомбинированы, чтобы получить общую стоимость каждого заказа; затем отображается средняя совокупная стоимость каждого заказа с группированием по товарам и, наконец, выводится простая сводная диаграмма для анализа. Все это делается с помощью встроенного интерфейса и инструментов в PowerPivot и Excel.

    Надстройка PowerPivot


    Рис. 3. Надстройка PowerPivot

    Теперь рассмотрим пример того, как создать клиентскую функциональность OData на другой платформе: iOS. Клиентская библиотека OData для iOS позволяет создавать приложения на этой платформе (например, для iPad и iPhone), которые используют существующие сервисы OData. Библиотека iOS для OData включает утилиту для генерации кода, odatagen, которая создает набор прокси-классов на основе метаданных сервиса. Прокси-классы обеспечивают средства для генерации OData URI, десериализации ответа в клиентские объекты и вызова операций создания, чтения, обновления и удаления (create, read, update and delete, CRUD) в сервисе. Следующий фрагмент кода показывает пример выполнения запроса на получение набора клиентов (customers) от сервиса OData:

    DataServiceQuery и QueryOperationResponse применяются для выполнения запроса путем формирования URI и его передачи сервису.

    Клиентская библиотека OData для iOS позволяет создавать приложения на этой платформе (например, для iPad и iPhone), которые используют существующие сервисы OData.

    Библиотека Windows Phone 7

    Теперь я продемонстрирую пример использования библиотеки OData на третьей платформе. О применении OData на других платформах я давал очень краткий обзор, но в данном случае я подробно опишу все этапы, необходимые для создания приложения, управляемого данными, на платформе Windows Phone 7, используя новый инструментарий Windows Phone 7.1 (Mango). Это приложение будет работать с тем же сервисом Northwind, который я задействовал в предыдущих двух примерах (по надстройке PowerPivot для Excel и библиотеке для iOS).

    Использование диалога Add Service Reference


    Рис. 4. Использование диалога Add Service Reference

    В Visual Studio Tools for Windows Phone 7 также включена утилита командной строки, которая позволяет выполнять тот же этап генерации кода. В любом случае в результате генерации кода создается класс клиентского прокси (DataServiceContext) для взаимодействия с сервисом и набор прокси-классов, отражающих профиль сервиса.

    Open Data Protocol Visualizer

    OGDI-сервис данных, по сути, является «черным ящиком» для стороннего разработчика, который создает приложение, использующее данные от этого сервиса. К счастью, OGDI-сервис предоставляет свои данные по протоколу OData, поэтому знать детали внутреннего устройства сервиса для взаимодействия с ним не требуется. Модель программирования этого сервиса — протокол OData. Конечная точка сервиса описывает форму данных и, как я показывал в предыдущем разделе, это все, что вам нужно знать для взаимодействия с сервисом. Однако зачастую полезно видеть форму данных в сервисе и лучше понимать взаимосвязи между частями сервиса. Именно с этой целью и был создан Open Data Protocol Visualizer. Он доступен из меню Tools | Extension Manager в Visual Studio 2010. На рис. 13 даны два представления, с помощью которых этот визуализатор отображает структуру данного OGDI-сервиса.

    Верхнее представление на рис. 13 показывает сервис в целом, а представление внизу масштабируется так, чтобы было видно лишь четыре блока. Визуализатор представляет наборы сущностей блоками, а отношения между ними — линиями, соединяющими эти блоки. Судя по представлению на рис. 13, ясно, что OGDI-сервис совершенно линеен и не содержит вообще никаких взаимосвязей, так как между блоками нет ни одной соединительной линии. Это особенность данного OGDI-сервиса, не типичная для большинства других OData-сервисов. В нижнем представлении хорошо видно, что сервис предоставляет данные о пожарных станциях, начальных школах, клиниках, где проводят диализ, и о государственных учреждениях, а также свойства и ключи для каждого типа этих сущностей.

    image: Open Data Visualizer Views of the OGDI Sample Service


    Рис. 13. Представления сервиса-примера OGDI в Open Data Protocol Visualizer

    Где узнать больше

    Выражаю благодарность за рецензирование статьи эксперту: Элизе Фласко (Elisa Flasko) и Майку Фласко (Mike Flasko)

    Читайте также: