WTF is WCF OData

Вообще странно получается: когда начинаеш изучать новую технологию, или догонять то что уже упущенно — и пытаешся писать блог посты про это — понимаеш что вокруг ещё много всего интересного про что хочется почитать. Сегодня я наткнулся на интересную технологию. Вернее даже так — я использовал ее раньше, я даже писал свои сервисы на этой технологии и слушал про нее в Сербии. И эта тахнология — это OData Services.

Давным — давно эта технология называлась ADO.Net Data Services, но теперь имеет более прозаичное название WCF Data Services.

Что это такое и с чем его едят?
Собственно WCF сервисы данных появились достаточно давно , в 2008 году, где поставлялся с .Net Framework 3.5 SP1. В двух словах WCF Data Services — это такие сервисы которые реализуют доступ к данным по OData протоколу, потому чтобы ответить на вопрос о том, что такое сервисы данных надо копнуть глубже.
Итак:
Odata — это такой протокол который определяет работы с ресурсами на основе ХТТП комманд: PUT,POST, DELETE, UPDATE и идентифицирует эти ресурсы по стандартному URI. Данные от сервиса к клиенту передаются с помощью двух стандартов: Atom или JSON.

С помощью следующих линков Вы можете почитать что такое эти стандарты:

The Atom Syndication Format — http://www.ietf.org/rfc/rfc4287.txt
JSON (JavaScript Object Notation) — http://json.org/

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

Если, например, вы работаете с Silverlight и изучили библиотеку OData для этой платформы, то можете программировать, используя любой канал OData.Также кроме такой библиотеки (библиотека для взаимодействия Silverlight & OData),
существуют аналогичные библиотеки для клиента Microsoft .NET Framework, AJAX, Java, PHP, Objective-C и др. Кроме того, Microsoft PowerPivot for Excel поддерживает канал OData (OData feed) как один из вариантов импорта данных в свое ядро анализа информации в памяти.

Так же, как клиенты, способные использовать протокол OData, могут работать с любым источником данных, к сервису или приложению, созданному с применением OData, могут обращаться любые клиенты с поддержкой OData. Создав веб-сервис, предоставляющий реляционные данные как конечную точку OData (или предоставляющий данные на сайте SharePoint, таблицах в Windows Azure и т. д.), вы можете легко сконструировать полнофункциональный настольный клиент в .NET Framework или веб-сайт на основе AJAX с богатой функциональностью, способный использовать эти данные.

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

ADO.NET Data Services (под кодовым название «Astoria») — платформа для Microsoft Data Services, нацеленная, в первую очередь, на использование таких современных технологий, как Ajax и Silverlight. Цель ADO.NET Data Services состоит в том, чтобы представить данные в виде сервиса, который может быть потреблен интернет клиентами в корпоративной сетях и через Интернет с использованием URI. Для создания такого сервиса данных необходимо создать ADO.NET Entity Data Model (EDM), то есть описать все объекты предметной области и задать связи между ними (создать EDM можно автоматически на основании базы данных). После этого, создав сервис и запустив его на выполнение, можно обращаться к базе данных посредством URI. При помощи HTTP методов GET, POST, PUT и DELETE, можно соответственно получить, создавать, обновлять и удалять записи базы данных. При этом обмен данными осуществляется с помощью форматов XML и JSON.

Просто представте ситуацию, когда Вы будете не привязанны ни к технологии которая будет использывать Ваш сервис, ни к хранилищу данных которые будут использованны Вашим сервисом.

Для того чтобы лучше понимать что такое OData Services давайте создадим тестовое приложение. Для начала, нам необходимо создать обычное ASP.Net приложение которое поможет нам создать наш сервис.

После того как мы создали наше приложение, нам необходимо создать репрезентацию наших данных. Идеально для нашего случая подходит Entity Framework модель, которая будет предаставлять магазин запчастей.

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

USE [PartsShop]
GO
/****** Object:  Table [dbo].[PartsType]    Script Date: 02/22/2011 00:51:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[PartsType](
	[ID] [int] NOT NULL,
	[PartType] [nvarchar](max) NULL,
 CONSTRAINT [PK_PartsType] PRIMARY KEY CLUSTERED
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  Table [dbo].[Parts]    Script Date: 02/22/2011 00:51:37 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[Parts](
	[ID] [int] NOT NULL,
	[PartName] [nvarchar](max) NULL,
	[PartPrice] [int] NULL,
	[Type] [int] NOT NULL,
 CONSTRAINT [PK_Parts] PRIMARY KEY CLUSTERED
(
	[ID] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  ForeignKey [FK_Parts_PartsType]    Script Date: 02/22/2011 00:51:37 ******/
ALTER TABLE [dbo].[Parts]  WITH CHECK ADD  CONSTRAINT [FK_Parts_PartsType] FOREIGN KEY([Type])
REFERENCES [dbo].[PartsType] ([ID])
GO
ALTER TABLE [dbo].[Parts] CHECK CONSTRAINT [FK_Parts_PartsType]
GO

После того как мы создали необходимые таблички, нам нужно создать EF модель которая будет представлять наши данные. Давайте назовем модель PartsShop.

После добавления модели, давайте создадим необходимый сервис:
add->new Item->Web->Wcf Data Service

Шаблон созданного сервиса будет иметь приблизительно такой вид:

    public class CarShopService : DataService< /* TODO: put your data source class name here */ >
    {
        // This method is called only once to initialize service-wide policies.
        public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            // config.SetEntitySetAccessRule("MyEntityset", EntitySetRights.AllRead);
            // config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }

Как видим, в шаблоне есть коммент TODO, что значит нам необходимо сделать изменения:) Каждые Data Service должен быть привязан к типам которые он будет возвращать или модифицировать, потому давайте зададим тип объектов с которыми будет работать наш сервис:

    public static void InitializeService(DataServiceConfiguration config)
        {
            // TODO: set rules to indicate which entity sets and service operations are visible, updatable, etc.
            // Examples:
            config.SetEntitySetAccessRule("Parts", EntitySetRights.AllRead);
            config.SetEntitySetAccessRule("PartsType", EntitySetRights.AllRead);
            //config.SetServiceOperationAccessRule("MyServiceOperation", ServiceOperationRights.All);
            config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        }
    }

Вот собственно и все — мы создали наш первый WCF сервис!
Теперь мы можем смотреть данные в нашей базе даже используя обычный браузер. Чтобы получить пример как оно выглядит через браузер зайдите по следующей линке:
http://www.odata.org/producers

и откройте любой понравившийся линк. Открывать лучше всего в Internet Explorer потому как под другими браузерами все выглядело достаточно уныло.

Если вы обратите внимание то вы можете фильтровать данные которые возвращенны от сервиса просто изменяя URI. Например:
http://odata.microsoftpdc.com/ODataSchedule.svc/

откроет список типов которые живут в базе данного ресурса, а в тоже время:
http://odata.microsoftpdc.com/ODataSchedule.svc/TimeSlots
вернет список объектом типа TimeSlot.

Использую URI, существует несколько форматов аддресса с помощью которых вы можете регулировать даныые которые будут возврщенны от сервиса.

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

Собственно протокол к данным Odata можна представить не только в связке SQL Server + EF ,но и такие приложения как SharePoint, Azure Tables, SQL Azure!
Так как в данный момент я очень активно работаю с Azure Tables & SQL Azure, хочу привести цитату с Odata.Org:

Microsoft SQL Azure

If you have a SQL Azure database account you can easily expose an OData service through a simple configuration portal. You can select authenticated or anonymous access and expose different OData views according to permissions granted to the specified SQL Azure database user.

Windows Azure Table Storage
Windows Azure Table provides scalable, available, and durable structured storage in the form of tables exposed as OData services.

Что удивило меня больше всего, так это тот факт что даже такие монстры как IBM WebSphere предалагют доступ к данным через этот чудесный протокол.

На что ещё стоит обратить внимание?

OData в PowerPivot

PowerPivot — новый инструмент бизнес-анализа информации в памяти, поставляемый как надстройка для Microsoft Excel 2010; за более подробными сведениями обращайтесь на сайт powerpivot.com. Этот инструмент поддерживает импорт больших наборов данных из источника данных, выполнение комплексного анализа информации и генерацию отчетов. PowerPivot может импортировать данные из разнообразных источников, в том числе прямо из каналов OData. Выбор From Data Feeds в PowerPivot включает поддержку конечной точки OData-сервиса как адрес канала для импорта.

Что ещё интересно — так это тот факт, что вы можете стать одним из разработчиков данного протокола, всего лишь свяжитесь с коммандой этого проекта — и начните менять мир к лучшему уже сейчас!

Интересные ссылки по теме:
http://msdn.microsoft.com/ru-ru/magazine/ff714561.aspx — Создание полнофункциональных интернет-приложений с применением Open Data Protocol

http://msdn.microsoft.com/en-us/data/bb931106 — домашняя страничка WCF Data Services.

http://msdn.microsoft.com/en-us/data/ee720180 — много видео и статей для новичков.

http://msdn.microsoft.com/en-us/data/gg602479 — Data Services for IPhone

http://msdn.microsoft.com/en-us/data/gg602478 — Data Services for PHP

http://msdn.microsoft.com/en-us/data/gg589613 — Data Services & Windows Phone 7

http://www.odata.org — домашняя страничка протокола OData