Большая часть моей карьеры была потрачена на работу и внедрение распределенного промежуточного программного обеспечения. В середине 90-х я работал в головной компании Open Environment Corporation, работающей над инструментами DCE. Позже я работал на Iona, разрабатывая их следующее поколение CORBA ORB. В настоящее время я работаю в отделе Red Hat JBoss, который укоренен в промежуточном программном обеспечении Java. Итак, вы могли бы сказать, что у меня довольно богатая перспектива, когда дело доходит до промежуточного программного обеспечения.
Более года назад я познакомился с новым способом написания веб-сервисов под названием REST. REST — это использование принципов World Wide Web для создания приложений. REST означает REpresentational State Transfer и был впервые определен в диссертации доктора Roy Fielding . REST — это набор архитектурных принципов, которые задают следующие вопросы:
- Почему Всемирная паутина так распространена и повсеместна?
- Что делает веб масштаб?
- Как я могу применить архитектуру Интернета к своим собственным приложениям?
Хотя REST имеет много общего с более традиционными способами написания SOA-приложений, во многих важных аспектах он сильно отличается. Вы могли бы подумать, что мой опыт поможет понять этот новый способ создания веб-сервисов, но, к сожалению, это не так. Причина в том, что некоторые концепции REST трудно проглотить, особенно если вы написали успешные приложения SOAP или CORBA. Если ваша карьера основана на одной из этих старых технологий, вам придется преодолеть немного эмоционального багажа. Для меня это заняло несколько месяцев и много читалось. Для вас это может быть проще. Для других они никогда не выберут REST вместо чего-то вроде SOAP и WS- *. Я просто прошу вас сохранять непредвзятость и провести некоторые исследования, если я не смогу убедить вас, что REST является интригующей альтернативой WS- * Так…
Отличные архитектурные принципы
REST не зависит от протокола, но когда люди говорят о REST, они обычно имеют в виду REST по HTTP. Такие технологии, как SOAP, используют HTTP исключительно в качестве транспортного протокола и, таким образом, используют очень небольшое подмножество своих возможностей. Многие скажут, что WS- * использует HTTP исключительно для туннелирования через брандмауэры. HTTP на самом деле очень богатый протокол приложений, который дает нам такие вещи, как согласование контента и распределенное кэширование. Веб-сервисы RESTful стараются использовать HTTP полностью, используя определенные архитектурные принципы. Каковы эти RESTful принципы?
- Адресные ресурсы. Каждая «вещь» в вашей сети должна иметь идентификатор. С REST через HTTP каждый объект будет иметь свой собственный URI.
- Единый ограниченный интерфейс. При применении REST через HTTP придерживайтесь методов, предусмотренных протоколом. Это означает следование значениям GET, POST, PUT и DELETE на религиозной основе.
- Представительство ориентировано. Вы взаимодействуете со службами, используя представления этой службы. Объект, на который ссылается один URI, может иметь различные доступные форматы. Разным платформам нужны разные форматы. AJAX может понадобиться JSON. Приложению Java может потребоваться XML.
- Общайтесь без гражданства. Приложения без сохранения состояния легче масштабировать.
Давайте более подробно рассмотрим каждый из этих отдельных принципов.
Адресуемость
Адресуемость — это идея, что каждый объект и ресурс в вашей системе доступен через уникальный идентификатор. Это кажется легким делом, но, если подумать, стандартизированная идентификация объекта недоступна во многих средах. Если вы пытались реализовать переносимое приложение J2EE, вы, вероятно, знаете, что я имею в виду. В J2EE распределенные и даже локальные ссылки на сервисы не стандартизированы, поэтому переносимость действительно затруднена. Это не так уж сложно для одного приложения, но с новой популярностью SOA мы направляемся в мир, где разнородные приложения должны интегрироваться и взаимодействовать. Отсутствие такой простой вещи, как стандартизация адресуемой службы, добавляет целый комплекс аспектов интеграции.
В мире REST адресуемость решается с помощью URI. URI стандартизированы и хорошо известны. Любой, кто когда-либо использовал браузер, знаком с URI. Из URI мы знаем протокол объекта. Другими словами, мы знаем, как общаться с объектом. Мы знаем его хост и порт, а точнее, где он находится в сети. Наконец, мы знаем путь ресурса на его хосте, который является его идентификатором на сервере, на котором он находится.
Использование уникального URI для идентификации каждой из ваших услуг делает каждый из ваших ресурсов связываемым. Сервисные ссылки могут быть встроены в документы или даже электронные письма. Например, рассмотрим ситуацию, когда кто-то звонит в службу поддержки вашей компании с проблемой вашего SOA-приложения. Они могут отправить разработчикам ссылку на электронную почту о том, с каким именно сервисом возникли проблемы. Кроме того, данные, которые публикуют сервисы, также довольно легко могут быть объединены в большие потоки данных.
Рисунок 1-1
<order id="111">
<customer>http://customers.myintranet.com/customers/32133</customer>
<order-entries>
<order-entry>
<quantity>5</quantity>
<product>http://products.myintranet.com/products/111</product>
...
В этом примере у нас есть XML-документ, описывающий запись заказа электронной торговли. Мы можем ссылаться на данные, предоставленные различными подразделениями компании. Из этой ссылки мы можем не только получить информацию о связанном клиенте и продуктах, которые были куплены, но также у нас есть идентификатор услуги, из которой поступают эти данные. Мы точно знаем, где мы можем дальше взаимодействовать и манипулировать этими данными, если мы того пожелаем.
Единый, ограниченный интерфейс
Принцип REST ограниченного интерфейса — это, пожалуй, самая сложная пилота для опытного разработчика CORBA или SOAP. Идея заключается в том, что вы придерживаетесь конечного набора операций протокола приложения, по которому вы распространяете свои сервисы. Для HTTP это означает, что службы ограничены использованием методов GET, PUT, DELETE и POST. Давайте объясним каждый из этих методов:
- GET — операция только для чтения. Это одновременно идемпотентная и безопасная операция. Идемпотент означает, что независимо от того, сколько раз вы применяете операцию, результат всегда одинаков. Чтение документа HTML не должно изменять документ. Безопасный означает, что вызов GET вообще не меняет состояние сервера. Это, кроме загрузки запроса, операция не повлияет на сервер.
- PUT обычно моделируется как вставка или обновление. Это также идемпотент. При использовании PUT клиент знает идентификатор ресурса, который он создает или обновляет. Это идемпотент, потому что отправка одного и того же сообщения PUT более одного раза не влияет на базовый сервис. Аналогия — это документ MS Word, который вы редактируете. Независимо от того, сколько раз вы нажмете кнопку «Сохранить», файл, в котором хранится ваш документ, будет логически одним и тем же документом.
- УДАЛЕНИЕ используется для удаления услуг. Это также идемпотент.
- POST — единственная неидемпотентная и небезопасная операция HTTP. Это метод, в котором ограничения смягчаются, чтобы дать пользователю некоторую гибкость. В системе RESTFul POST обычно моделирует заводские услуги. Если с помощью PUT вы точно знаете, какой объект вы создаете, то с помощью POST вы полагаетесь на фабричный сервис для создания объекта для вас.
Вы можете почесать голову и подумать: «Как можно написать распределенный сервис, используя только 4 метода?» Ну … SQL имеет только 4 операции: SELECT, INSERT, UPDATE и DELETE. У JMS и других MOM действительно только два: отправить и получить . Насколько мощны оба этих инструмента? Как для SQL, так и для JMS, сложность взаимодействия ограничена исключительно моделью данных. Адресуемость и операции четко определены и конечны, а сложный материал делегирован модели данных (в случае SQL) или телу сообщения (в случае JMS).
Почему важен единый интерфейс?
Ограничение интерфейса для ваших веб-сервисов имеет гораздо больше преимуществ, чем недостатков. Давайте посмотрим на несколько:
фамильярность
Если у вас есть URI, который указывает на службу, вы точно знаете, какие методы доступны на этом ресурсе. Вам не нужен IDL-подобный файл с описанием доступных методов. Вам не нужны заглушки. Все, что вам нужно, это клиентская библиотека HTTP. Если у вас есть документ, который состоит из ссылок на данные, предоставленные различными службами, вы уже знаете, какой метод вызывать для извлечения данных из этих ссылок.
Interoperability
HTTP очень распространенный протокол. Большинство языков программирования имеют доступную клиентскую библиотеку HTTP. Таким образом, если ваш веб-сервис предоставляется через REST, очень вероятно, что люди, которые хотят использовать ваш сервис, смогут без каких-либо дополнительных требований, кроме возможности обмениваться форматами данных, которые ожидает сервис. С CORBA или WS- * вы должны установить клиентские библиотеки конкретного производителя. У кого из вас возникла проблема с взаимодействием поставщиков CORBA или WS- *? Это традиционно было очень проблематично. Набор спецификаций WS- * также был движущейся целью на протяжении многих лет. Таким образом, с WS- * и CORBA вам не только нужно беспокоиться о совместимости поставщиков, вы должны убедиться, что ваш клиент и сервер используют одну и ту же версию спецификации. С REST через HTTP вы нене нужно беспокоиться об этих вещах и просто сосредоточиться на понимании формата данных службы. Мне нравится думать, что вы сосредоточены на том, что действительно важно:совместимость приложений , а не совместимость с поставщиками .
Масштабируемость
Поскольку REST ограничивает вас четко определенным набором методов, у вас предсказуемое поведение, которое может иметь невероятные преимущества в производительности. GET — самый сильный пример. Поскольку GET является методом чтения, который является одновременно и идемпотентным, и безопасным, браузеры и прокси-серверы HTTP могут кэшировать ответы на серверах, что может сэкономить огромное количество сетевого трафика и попаданий на ваш сайт. Добавьте возможности заголовка Cache-Control в HTTP 1.1 , и у вас будет невероятно богатый способ определения политик кэширования для ваших сервисов.
Это не заканчивается кэшированием. Рассмотрим как PUT, так и DELETE. Поскольку они являются идемпотентными, клиенту или серверу приходится беспокоиться об обработке доставки дублирующихся сообщений. Это экономит много бухгалтерского учета и сложного кода.
Ориентация на представление
Третий архитектурный принцип REST заключается в том, что ваши сервисы должны быть ориентированы на представление. Каждый сервис адресуется через определенный URI, и представления обмениваются между клиентом и сервисом. С помощью операции GET вы получаете представление о текущем состоянии этого ресурса. PUT или POST передает представление ресурса на сервер, так что состояние базового ресурса может измениться.
В системе RESTful сложность взаимодействия клиент-сервер находится в пределах представлений, передаваемых взад и вперед. Этими представлениями могут быть XML, JSON, YAML или любой другой формат, который вы можете придумать. Одна действительно крутая вещь в HTTP — это то, что он обеспечивает простой протокол согласования контента между клиентом и сервером. Через заголовок Content-Type клиент указывает тип представления. С заголовком Accept клиент может перечислить свои предпочтительные форматы ответа. Клиенты AJAX могут запрашивать JSON, Java для XML, Ruby для YAML. Еще одна вещь, для которой это очень полезно, это управление версиями сервисов. Один и тот же сервис может быть доступен через один и тот же URI с теми же методами (GET, POST и т. Д.), И все, что изменяется, — это тип mime. Например,тип mime может быть «application / xml» для старой службы, в то время как новые службы могут обмениваться типами mime «application / xml; schemaVersion = 1.1».
В общем и целом, поскольку REST и HTTP имеют многоуровневый подход к адресуемости, выбору методов и формату данных, у вас гораздо более разобщенный протокол, который позволяет вашей службе согласованно взаимодействовать с широким кругом различных клиентов.
Общаться без гражданства
Последний принцип RESTful, о котором я расскажу, — это идея безгражданства. Когда я говорю о безгражданстве, я не имею в виду, что ваши приложения не могут иметь состояние. В REST без сохранения состояния означает, что на сервере не хранятся данные сеанса клиента. Сервер только записывает и управляет состоянием ресурсов, которые он предоставляет. Если требуются специфичные для сеанса данные, они должны храниться и поддерживаться клиентом и передаваться на сервер при каждом запросе по мере необходимости. Уровень обслуживания, который не должен обслуживать клиентские сеансы, гораздо легче масштабировать, поскольку он должен выполнять намного более дешевые репликации в кластерной среде. Его гораздо проще масштабировать, так как все, что вам нужно сделать, это добавить машины.
Мир без серверных данных сеансов не так сложно представить, если оглянуться назад на 12-15 лет назад. В то время во многих распределенных приложениях имелся толстый клиент с графическим интерфейсом, написанный на RPC для Visual Basic, Power Builder или Visual C ++, со средним уровнем, который находился перед базой данных. Сервер был без состояния и только что обработал данные. Толстый клиент удерживал все состояние сеанса. Проблема с этой архитектурой была операционной. Операциям было очень сложно обновлять, исправлять и поддерживать клиентские графические интерфейсы в больших средах. Веб-приложения решили эту проблему, потому что приложения могли доставляться с центрального сервера и обрабатываться браузером. Мы начали поддерживать клиентские сессии на сервере из-за ограничений браузера. Теперь, около 2008 года, с растущей популярностью AJAX, Flex и Java FX,браузеры достаточно сложны, чтобы поддерживать свое собственное состояние сеанса, как это делали их аналоги толстого клиента в середине 90-х годов. Теперь мы можем вернуться к тому масштабируемому среднему уровню без сохранения состояния, которым мы пользовались в прошлом. Забавно, что иногда дела идут по кругу.
Вывод
REST определяет ключевые архитектурные принципы того, почему Всемирная паутина настолько распространена и масштабируема. Следующим шагом в эволюции сети является применение этих принципов к семантической сети и миру веб-сервисов. REST предлагает простой, совместимый и гибкий способ написания веб-сервисов, который может сильно отличаться от механизмов RPC, таких как CORBA и WS- *, в которых обучались многие из нас.
Эта статья является первой из двух частей. В этой статье я хотел познакомить вас с основными понятиями REST. В моей следующей статье «Перевод Java в REST» мы создадим очень простой сервис RESTful в Java с использованием нового стандарта JCP JAX-RS . Другими словами, вы увидите, как теория претворяется в жизнь. До тех пор я призываю вас прочитать больше о REST. Ниже приведены некоторые интересные ссылки.
Прочитайте Часть II этой серии: Помещение Java в REST
связи
об авторе
Он регулярно ведет блог на bill.burkecentral.com .