Станция техобслуживания

Введение в службы RESTful с использованием WCF

Джон Фландерс (Jon Flanders)

Загружаемый файл с кодом доступен в коллекции кода MSDN
Обзор кода в интерактивном режиме

Cодержание

Знакомство с REST
Абстрактный пример
Для чего нужен REST?
WCF и REST
WebGetAttribute и WebInvokeAttribute
UriTemplate и UriTemplateTable
WebHttpBinding и WebHttpBehavior
WebServiceHost и WebServiceHostFactory
Использование кода примеров

Этой статьей открывается серия статей, посвященных созданию служб Windows Communication Foundation (WCF) с использованием стиля REST (Representational State Transfer — репрезентативная передача состояния). Можно даже сказать, что в рубрике «Станция техобслуживания» 2009-ый год будет годом REST, и, по-моему мнению, это должно было произойти намного раньше. REST остается популярным стилем в течение многих лет, начиная с его появления в 2000 году.

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

Знакомство с REST

Архитектурный стиль представляет собой набор ограничительных условий, применяемых при каком-либо конструировании. Архитектурный стиль программных средств является описанием компонентов, которые могут быть использованы для реализации программной системы. REST представляет собой архитектурный стиль, который можно использовать для создания программных средств, в которых клиенты (агенты пользователей) могут отправлять запросы службам (конечным точкам). REST является одним из способов реализации архитектурного стиля «клиент-сервер» — по сути, REST явно опирается на архитектурный стиль «клиент-сервер».

Человек по имени Рой Томас Филдинг (Roy Thomas Fielding) первым ввел термин REST в качестве концепции в своей диссертации на степено доктора философии «Архитектурные стили и проектирование архитектур программных систем, поддерживающих работу в сети»). Он был одним из тех, кто работал над спецификацией, определяющей сегодня функционирование Интернета: протоколом HTTP (Hypertext Transfer Protocol, протокол передачи гипертекста). Обычно подготовка людей в области описания архитектурного стиля не имеет значения при обсуждении стиля, но в данном случае, полагаю, это важно, поскольку я считаю, что для лучшего понимания основных принципов REST необходимо понять, что такое Интернет и как он работает.

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

  • Агенты пользователей взаимодействуют с ресурсами, которыми может быть всё, что можно поименовать и представить. К каждому ресурсу можно обратиться посредством уникального идентификатора URI (Uniform Resource Identifier — универсальный код ресурса).
  • Взаимодействие с ресурсами (обнаруживаемыми посредством их уникальных кодов URI) осуществляется с помощью единого интерфейса стандартных команд HTTP (GET, POST, PUT и DELETE). Для взаимодействия важно также объявить тип мультимедийного ресурса, который указывается с помощью заголовка типа содержимого HTTP. (XHTML, XML,.png, PNG и JSON — некоторые хорошо известные мультимедийные типы.)
  • Ресурсы описывают себя сами. Вся информация, необходимая для обработки запроса ресурса, содержится в самом запросе (это позволяет обходиться без характеристики состояния служб).
  • В ресурсах содержатся ссылки на другие ресурсы (гиперсреда).

Абстрактный пример

Служба, использующая архитектурный стиль REST, обычно ссылается на службу RESTful или конечную точку. Приведу небольшой пример, чтобы дать читателю представление об идеях, на которых основывается архитектурный стиль. Представим, что мне требуется служба, работающая с данными по журналу MSDN Magazine — служба, сообщающая все годы, когда публиковался MSDN Magazine, и все статьи в каждом выпуске. Предположим, что требуется, чтобы редакторы журнала могли использовать эту службу для добавления новых статей и управления данными для предстоящих выпусков.

При создании служб RESTful можно достичь требуемого результата, выполнив несколько крайне простых основных этапов.

  1. Какие ресурсы предполагается использовать?
  2. Какие идентификаторы URI предполагается использовать для представления этих ресурсов?
  3. Какую часть единого интерфейса (команды HTTP) будет поддерживать каждый из URI?

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

Теперь я приступаю к конструированию гипотетической службы с использованием этих основных этапов. Ресурсами являются все годы, в течение которых публиковался журнал MSDN Magazine, все выпуски каждого года и все статьи, опубликованные в каждом из выпусков журнала. Для представления этих ресурсов в рамках этого частного примера будет использоваться мультимедийный тип application/xml (XML), но важно помнить, что службы RESTful ни в коем случае не ограничиваются типом XML в качестве мультимедийного типа.

Кроме этого мне требуется определить для всех ресурсов идентификаторы URI. В данный момент необходимо определить только относительные идентификаторы URI, поскольку абсолютный идентификатор URI определяется тем, где будет размещена конечная точка. Список годов будет корневым идентификатором URI службы (/). При использовании этого синтаксиса выражение /{year} возвращает все выпуски за все годы; /{year}/{issue} дает идентификатор URI каждого выпуска (каждый выпуск будем идентифицировать месяцем его публикации); а /{year}/{issue}/{article} представляет каждую статью (исходим из предоположения, что все статьи каждого выпуска пронумерованы от 1 до n).

Затем выполняется сопоставление идентификаторов URI и единого интерфейса. Поскольку архив журнала должен быть доступен только для чтения, корневой ресурс будет предоставлять только команду GET. Новый год можно добавить, выполнив PUT для URI /{year}. PUT используется для создания новых ресурсов, если клиенту известен идентификатор URI нового ресурса, как это будет в данном случае. PUT можно также использовать для обновления существующих ресурсов, если известен идентификатор URI. POST используется для создания ресурса, когда клиенту не известен идентификатор URI нового ресурса, поэтому я буду использовать команду POST при добавлении нового ресурса статьи, который будет передаваться для /{year}/{issue} URI.

Я могу продолжить обсуждение всех ресурсов и команд, но, надеюсь, вы уже поняли, какие действия необходимы для определения проекта конечной точки RESTful. Полный список ресурсов, идентификаторов URI и команд приведен на рис. 1.

Рис. 1 Поддержка операционных систем
Ресурс Идентификатор URI Команды
Все годы "/ " GET
Выпуски конкретного года "/{year}" GET, PUT
Конкретный выпуск "/{year}/{issue}" GET, PUT
Статья "/{year}/{issue}/{article}" GET, POST (номер статьи присваивается системой), PUT, DELETE (возможность удаления отключается сразу после публикации выпуска)

Если мне как клиенту потребуются статьи за январь 2006 г., следует выполнить команду HTTP GET для выпуска /2006/January. Если бы я был редактором, и мне требовалось бы добавить статью в выпуск за декабрь 2008 г., клиент выполнил бы команду POST с ресурсом статьи для /2008/December, и новая статья добавилась бы к этому выпуску. Этот шаблон будет многократно использоваться при потреблении службы в качестве клиента.

Для чего нужен REST?

Теперь, когда я рассказал кое-что о REST, возможно, вы хотите узнать, зачем он вам нужен. Будучи разработчиком, вы должны испытывать потребность в изучении и освоении любого стиля, технологии или шаблона. Если вы регулярно читаете этот журнал, вероятно, вы являетесь разработчиком, использующим технологии Майкрософт. А для реализации приложений «клиент-сервер» вы, вероятно, использовали другой архитектурный стиль: вызов удаленных процедур (RPC). Использовали вы стандартные системы RPC, такие как DCOM или .NET Remoting, или технологии RPC, допускающие взаимодействие, такие как SOAP с использованием ASMX или WCF, все это реализации стиля «клиент-сервер», имеющиеся в платформе Майкрософт. Так зачем же изучать и применять REST?

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

Далее следует список других преимуществ (не следует думать, что это исчерпывающий список).

Кэширование Когда у конечных точек RESTful запрашиваются данные с помощью HTTP, используется команда HTTP GET. Ресурсы, возвращаемые в ответ на запрос GET, можно кэшировать множеством разных способов. Условная команда GET, которая дает клиенту способ проверить с помощью службы, является ли его версия данных по-прежнему текущей, является деталью реализации, которую может обеспечить конечная точка RESTful, и которая еще больше увеличивает скорость и масштабируемость.

Расширение REST дает возможность включать в каждый ресурс все состояния, необходимые для обработки конкретного запроса. Службы RESTful намного проще масштабировать, если они выполняют это ограничение и могут обходиться без поддержки состояния.

Побочные эффекты Службы RESTful не должны иметь никаких побочных эффектов, когда вы запрашиваете ресурс с помощью команды GET (к сожалению, это ограничение гораздо легче нарушить, чем некоторые другие ограничения REST).

Идемпотент Две других основных команды HTTP, обычно используемые в виде части единого интерфейса, это PUT и DELETE. Команда PUT чаще всего используется, когда агенту пользователя требуется изменить ресурс, а команда DELETE описывает себя сама. Важным моментом (и именно это описывает термин «идемпотент») является то, что на конкретном ресурсе эти две команды можно использовать несколько раз, и результат будет таким же, как при их первом использовании — по крайней мере, не будет никаких дополнительных воздействий. Это является обнадеживающим обстоятельством при создании надежных распределенных систем, в которых ошибки, сбои в сети или задержка могут привести к многократному выполнению кода.

Функциональная совместимость Многие рекламируют SOAP как наилучший способ реализации программ типа «клиент-сервер». Но для некоторых языков и сред до сих пор нет инструментальных средств SOAP. А некоторые снабжены инструментальными средствами, основанными на устаревших стандартах, которые не всегда обеспечивают возможность взаимодействия со средствами, в которых реализованы новые стандарты. Для REST требуется только доступность библиотеки HTTP для большинства операций (библиотека XML, безусловно, также часто оказывается полезной), и этот стиль определенно обладает большей функциональной совместимостью, чем любая из технологий RCP (включая SOAP).

Простота Это преимущество является более субъективным, чем другие, и разные люди понимают его по-разному. Для меня простота использования REST связана с идентификаторами URI, представляющими ресурсы, и единым интерфейсом. Как искушенный пользователь Интернета я умею вводить в обозревателе разные идентификаторы URI для получения доступа к различным ресурсам (иногда это называют «копанием» в URI или URL, но это ни в коем случае не является чем-то недостойным). Поскольку у меня имеется многолетний опыт такого использования кодов URI, создание URI для ресурсов кажется мне совершенно естественным. Использование единого интерфейса упрощает разработку, освобождая меня от необходимости создания интерфейса, контракта или интерфейса API для каждой службы, которую мне требуется создать. Интерфейс (способ взаимодействия клиентов с моей службой) определяется ограничениями, накладываемыми архитектурой.

Как было сказано, этот список не претендует на полноту и на то, чтобы быть окончательным свидетельством того, что REST является единственной и единственно правильной технологией, которую необходимо использовать во всех случаях. Следует иметь представление о преимуществах, чтобы со знанием дела использовать их в соответствующей ситуации.

WCF и REST

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

Хотя верно то, что WCF в основном предназначена для RPC (с помощью SOAP), на деле эта платформа была в состоянии предоставлять и потреблять службы REST, поскольку исходно она была выпущена как составная часть .NET Framework 3.0. Чего ей не хватало, так это модели программирования, необходимой для удобного использования REST совместно с WCF. Кроме этого, необходимо было создавать некоторые элементы инфраструктуры, чтобы обеспечить работу REST с .NET Framework 3.0. И модель программирования, и эти элементы инфраструктуры были добавлены в WCF в составе .NET Framework 3.5 в сборке System.ServiceModel.Web. Помимо этого несколько усовершенствований было добавлено в пакете обновления .NET Framework 3.5 SP1.

В центре модели программирования находятся два новых атрибута, WebGetAttribute и WebInvokeAttribute, а также механизм шаблона URI, позволяющий объявлять идентификатор URI и команду, на которую будет откликаться каждый из методов. Инфраструктура поступает в форме привязки (WebHttpBinding) и поведения (WebHttpBehavior), обеспечивающих требуемый для использования REST сетевой стек. Кроме этого, имеется некоторая поддержка размещающей инфраструктуры от пользовательских ServiceHost (WebServiceHost) и ServiceHostFactory (WebServiceHostFactory).

WebGetAttribute и WebInvokeAttribute

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

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

Значение Action основано либо на имени метода (плюс пространство имен вашей службы), либо на пользовательском значении (настроенном посредством свойства OperationContractAttribute.Action). Такая система маршрутизации тесно связана с SOAP, поскольку по умолчанию используется заголовок Action спецификации SOAP. К счастью, как почти всё остальное в WCF, эту инфраструктуру диспетчеризации можно заменить.

Когда инфраструктура REST используется совместно с WCF, диспетчер по умолчанию заменяется диспечером, выполняющим маршрутизацию не на основе Action, а на основе идентификатора URI поступающего запроса и используемой команды HTTP. Такая маршрутизация (выполняемая классом с именем WebHttpDispatchOperationSelector) позволяет без труда реализовать конечную точку RESTful. Этот диспетчер настраивается на каждой конечной точке посредством поведения с именем WebHttpBehavior, которе необходимо добавить к каждой конечной точке, из которой предполагается использовать эту модель программирования (хотя, как вы увидите далее, делать это вручную приходится нечасто).

Ключом к решению этой задачи является умение WebHttpDispatchOperationSelector сопоставлять вашим методам разные идентификаторы URI и команды. Для этого WebGetAttribute и WebInvokeAttribute необходимо добавить к методам типа WCF ServiceContract.

WebGetAttribute сообщает диспетчеру, какой метод должен откликаться на запросы HTTP GET. WebInvokeAttribute сопоставляется HTTP POST по умолчанию, но свойство WebInvokeAttribute.Method можно настроить на поддержку любой другой команды HTTP (PUT и DELETE являются двумя самыми распространенными). По умолчанию идентификатор URI определяется именем метода (добавленном на основном идентификаторе URI конечной точки).

В действительности это не очень соотвествует RESTful, так как не хотелось бы иметь дело с именами методов, поскольку они представляют команды (глаголы). В качестве идентификатора URI предпочтительнее использовать существительные. По этой причине модель программирования REST в WCF позволяет настраивать идентификаторы URI для каждого метода с помощью шаблонов, которые можно настривать посредством свойства UriTemplate атрибута WebGetAttribute или WebInvokeAttribute.

UriTemplate и UriTemplateTable

Для активирования настройки идентификатора URI для всех сочетаний метода и команды в WCF добавлена возможность определять идентификатор URI для каждого ресурса с помощью специального синтаксиса шаблонов, такого, как был использован ранее в этой статье для описания конечной точки службы MSDN Magazine. Этот синтаксис дает возможность определять (с использованием заменяемых лексем) структуру идентификатора URI, которую будет представлять каждый метод в сочетании с командой HTTP (посредством WebGetAttribute или WebInvokeAttribute). Подробнее этот синтаксис будет обсуждаться в следующей статье.

На рис. 2 показано определение WCF ServiceContract для службы MSDN Magazine (с соответствующими атрибутами и с настройками UriTemplate), и применяются возможности, упоминавшиеся ранее. Здесь расширяется существующая система определений контракта WCF с помощью атрибута WebGetAttribute для тех операций, которые должны откликаться на команду GET. Кроме этого, к операции добавляется атрибут WebInvokeAttribute для отклика на любые другие команды.

Рис. 2. Определение ServiceContract WCF

[ServiceContract]
public interface IMSDNMagazineService
{
    [OperationContract]
    [WebGet(UriTemplate="/")]
    IssuesCollection GetAllIssues();
    [OperationContract]
    [WebGet(UriTemplate = "/{year}")]
    IssuesData GetIssuesByYear(string year);
    [OperationContract]
    [WebGet(UriTemplate = "/{year}/{issue}")]
    Articles GetIssue(string year, string issue);
    [OperationContract]
    [WebGet(UriTemplate = "/{year}/{issue}/{article}")]
    Article GetArticle(string year, string issue, string article);
    [OperationContract]
    [WebInvoke(UriTemplate = "/{year}/{issue}",Method="POST")]
    Article AddArticle(string year, string issue, Article article);

}

В этом случае выражение Method="POST" добавлено в метод AddArticle для удобочитаемости, поскольку по умолчанию атрибуту WebInvokeAttribute соответствует команда POST. Для обоих методов, GET и POST, настройка URI осуществляется с помощью атрибута UriTemplate. Отмечу, что синтаксис UriTemplate предусматривает несколько переменных сегментов пути, и все этих сегменты пути передаются методам в качестве аргументов.

WebHttpBinding и WebHttpBehavior

В WCF привязка определяет способ, которым WCF будет обмениваться данными. В действительности привязка является настройкой, сообщающей WCF, как создавать то, что известно под названием стека канала, представляющего собой набор объектов, которые будут совместно работать для обеспечения требуемого для конкретной конечной точки типа передачи данных.

Для конечной точки RESTful используется привязка WebHttpBinding. В отличие от многих других привязок, WebHttpBinding крайне проста и содержит только два компонента: транспорт HTTP и кодировщик текстовых сообщений (настроенный на использование не SOAP, а простого XML).

Как было упомянуто ранее, WebHttpBehavior является объектом, вызывающим использование диспетчера URI-плюс-команда, поэтому WebHttpBinding и WebHttpBehavior почти всегда используются совместно. Далее следует код для создания такой конечной точки для случая самостоятельного размещения конечной точки WCF RESTful.

ServiceHost sh = 
  new ServiceHost(typeof(MSDNMagazineServiceType));
string baseUri = "http://localhost/MagazineService";
ServiceEndpoint se = 
  sh.AddServiceEndpoint(typeof(IMSDNMagazineService),
  new WebHttpBinding(), baseUri);
se.Behaviors.Add(new WebHttpBehavior());
sh.Open();

Обратите внимание, что мне требуется не только указать WebHttpBinding при добавлении конечной точки к ServiceHost, мне требуется также явно добавить WebHttpBehavior к конечной точке, чтобы заставить работать систему диспетчеризации URI-плюс-команда. Конечно, этого можно было бы добиться посредством настройки (см. рис. 3).

Рис. 3 Диспетчеризация URI-плюс-команда в настройке

<configuration>
  <system.serviceModel>
    <services>
      <service name="MSDNMagazine.MSDNMagazineServiceType">
        <endpoint 
          address="http://localhost/MagazineService" 
          binding="webHttpBinding" 
          contract="MSDNMagazine.IMSDNMagazineService" 
          behaviorConfiguration="webby"/>
      </service>
    </services>
    <behaviors>
      <endpointBehaviors>
        <behavior name="webby">
          <webHttp/>
        </behavior>
      </endpointBehaviors>
    </behaviors>
  </system.serviceModel>
</configuration>

WebServiceHost и WebServiceHostFactory

Одной из жалоб на WCF является то, что иногда она слишком сложна, особенно в терминах настройки. Для смягчения этого осложнения с конечными точками RESTful (повторюсь, что простота является одним из часто декларируемых преимуществ REST) в Майкрософт добавили два новых типа, WebServiceHost и WebServiceHostFactory, в платформу .NET Framework 3.5.

WebServiceHost является типом, производным от ServiceHost, что упрощает самостоятельное размещение конечных точек RESTful. Код для самостоятельного размещения посредством WebServiceHost выглядит следующим образом.

string baseUri = "http://localhost/MagazineService";
WebServiceHost sh = 
  new WebServiceHost(typeof(MSDNMagazineServiceType),
  new Uri(baseUri));
sh.Open();

Это удачная оптимизация, поскольку в ней отсутствует повторяющийся код для добавления WebHttpBinding и WebHttpBehavior вручную. Класс WebServiceHost автоматически создает конечную точку и настраивает ее посредством WebHttpBinding и WebHttpBehavior.

В случае размещения внутри служб IIS, управляемого WCF, среде WCF обычно требуется файл .svc, указывающий на тип службы, а также записи в файле web.config, информирующие WCF о конечной точке (привязке и поведениях среди прочих параметров настройки).

Для упрощения управляемого размещения специалисты Майкрософт добавили WebServiceHostFactory, которая в случае управляемого размещения использует открытую точку расширения WCF (с помощью пользовательского типа ServiceHostFactory) для создания не требующей настройки рабочей среды для многих служб RESTful. Файл .svc выглядит примерно так.

<%@ ServiceHost Factory=
  "System.ServiceModel.Activation.WebServiceHostFactory"   
  Service="MSDNMagazine.MSDNMagazineServiceType" %>

WebServiceHostFactory создает экземпляр WebServiceHost, и, поскольку WebServiceHost автоматически выполнит настройку конечной точки с помощью WebHttpBinding и WebHttpBehavior, в файле web.config не требуется вообще никакой настройки для этой конечной точки. (Безусловно, если требуется настраивать привязку, необходимо использовать систему настройки или создать класс, являющийся производным от WebServiceHost/WebServiceFactory). Если бы мне требовалось настраивать привязку, можно было бы по- прежнему добавлять соответствующие записи в файл настройки. На рис. 4 показан файл настройки, который включает обычную проверку подлинности HTTP на конечной точке моей службы.

Рис. 4 Активирование обычной проверки подлинности

<configuration>
<system.serviceModel>
  <services>
    <service name="MSDNMagazine.MSDNMagazineServiceType">
      <endpoint 
        address="http://localhost/MagazineService" 
        binding="webHttpBinding" 
        contract="MSDNMagazine.IMSDNMagazineService" 
        behaviorConfiguration="webby"/>
    </service>
  </services>
  <bindings>
    <webHttpBinding>
      <binding name="secure">
        <security mode="Transport">
          <transport clientCredentialType="Basic"/>
        </security>
      </binding>
    </webHttpBinding>
  </bindings>
  <behaviors>
    <endpointBehaviors>
      <behavior name="webby">
        <webHttp/>
      </behavior>
    </endpointBehaviors>
  </behaviors>
</system.serviceModel>
</configuration>

Использование кода примеров

В процессе обсуждения возможностей WCF в связи с технологией REST я изложил большую часть реализации службы, предложенной в начале статьи. Давайте обсудим процедуру взаимодействия с этой службой.

После того, как служба создана и запущена, я могу использовать ее корневой идентификатор URI в любом клиенте, включая веб-обозреватель, например Internet Explorer. Возможность выполнять быстрые проверки конечных точек RESTful с помощью обозревателя является (с этим согласится большинство) весьма полезным следствием применения архитектурного стиля REST, основывающегося на принципе функционирования Интернета. Результат показан на рис. 5.

fig05.gif

Рис. 5 Корневой идентификатор URI ресурса

В этом случае я выполняю размещение на сервере разработки веб-приложений Visual Studio 2008, который определяет основной идентификатор URI. Файл Issues.svc является необходимым для WCF файлом в случае управляемого размещения. Если мне требуется просмотреть результат для конкретного года, я могу просто добавить этот год к адресу (URI) в обозревателе (см. рис. 6).

fig06.gif

Рис. 6 Ресурс, представляющий 2007 год

Если бы я запрашивал октябрь 2008 г., идентификатор URI имел бы вид localhost:1355/Issues.svc/2008/October, который в данный момент был бы пустым набором. А если бы мне потребовалось добавить статью, я бы выполнил команду HTTP POST для этого идентификатора URI с представлением XML статьи в качестве тела запроса HTTP.

Еще одной приятной особенностью HTTP являются все средства, доступные для взаимодействия с ним. Одним из моих любимых является Fiddler, позволяющий мне «шпионить» за запросами и ответами HTTP. Но он обладает также возможностью, позволяющей мне выполнять произвольные операции HTTP. Поэтому я могу использовать вкладку «Конструктор запросов Fiddler» для выполнения команды HTTP POST (см. рис. 7). На рис. 8 запрос ресурса для октября 2008 г. находится после команды POST.

fig07.gif

Рис. 7 Формирование запроса HTTP POST для создания нового ресурса статьи посредством Fiddler

fig08.gif

Рис. 8 Ресурс стать добавлен

Хотя можно оспаривать то, что Internet Explorer и Fiddler являются настоящими клиентами, создание настоящей реализации «клиент-сервер» является расширением продемонстрированных в статье простых этапов (более сложный пример создания клиента RESTful будет представлен в предстоящей статье). Клиенту необходимо знать идентификатор URI каждого ресурса и то, какие части единого интерфейса должны использоваться с каждым из идентификаторов URI. Тогда, используя эти сведения, клиент сможет взаимодействовать со службой для настройки своих функций.

В этой первой статье было показан основной набор компонентов WCF, позволяющий без труда использовать архитектурный стиль REST в приложениях .NET. Эта основа делает возможным использование других интересных технологий, включая такие как веб-каналы (RSS и Atom), и поддержку для взаимодействия с AJAX ресурсов, закодированных с использованием JSON.

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

Вопросы и комментарии направляйте по адресу sstation@microsoft.com.

Джон Фландерс (Jon Flanders) - независимый консультант, лектор и преподаватель в компании Pluralsight. Он специализируется на Windows Workflow Foundation, BizTalk Server и Windows Communication Foundation. Связаться с Джоном можно по адресу masteringbiztalk.com/blogs/jon.