[Перевод] RESTful: Что это на самом деле значит

94cedb19d0e347ffb32f9a47a149ad19.jpg

Как оскорбить разработчика via Geek & Poke

Мы в 1cloud занимаемся построением облачного сервиса — наши пользователи могут заказывать у нас виртуальные серверы, и очень часто на них запускаются сайты. Мы уже рассказывали о том, как ускорить загрузку веб-страниц, а сегодня поднимем еще одну интересную тему — каким на самом деле должны быть веб-приложения, чтобы считаться RESTful? Интересный материал на эту тему в блоге образовательного сервиса Recurse Center написала Лорен Лонг (Lauren Long) — мы представляем вашему вниманию адаптированный перевод этой заметки.

Если вы занимаетесь веб-программированием, то наверняка слышали о REST. Многие, такие как я, зачастую делают вид, что знают о нем все, но теряются, когда им задают вопрос, являются ли написанные ими приложения RESTful. «Я использую с html, получается RESTful, правильно?». Настало время раз и навсегда выяснить, что означает этот приятный слуху модный термин.

Что такое REST


REST — аббревиатура для Representational State Transfer (дословно что-то вроде «передача состояния представления»). Это набор принципов разработки, позволяющих сделать передачу данных в сети более гибкой и масштабируемой. Эти принципы отвечают на ряд вопросов: что есть базовые компоненты системы, как они взаимодействуют между собой, как мы можем быть уверенными, что разные части системы могут быть взаимозаменяемыми в любое время, как система может быть масштабирована для работы с миллиардами пользователей?

58d06ca29a374b54abdf0f74f99dc6af.jpg

Рой Филдинг во время выступления на OSCON08

Сам термин «REST» впервые был введен Роем Филдингом (Roy T. Fielding) в его кандидатской диссертации «Архитектурные стили и разработка интернет-ориентированной программной архитектуры» в 2000 году. На момент публикации его работы World Wide Web (то есть веб) уже была весьма популярной. Филдинг рассмотрел вопрос в ретроспективе и проанализировал черты, позволившие www стать более успешной, чем конкурирующие протоколы. Затем он сформулировал основные принципы, позволяющие сделать сетевое взаимодействие Web-like. REST — это общий набор инструментов, не заточенных исключительно под Web, но позволяющий подстраиваться под другие распределенные системы, в том числе, встроенные. Но REST — это и не протокол в прямом смысле. По крайней мере, пока в нем не прописаны четкие параметры выполнения.

Условия Филдинга


В своей диссертационной работе Филдинг приводит несколько параметров или условий для архитектуры системы, чтобы ее можно было считать RESTful. Ниже я приведу краткий обзор каждого из них и попытаюсь объяснить, как Web может им удовлетворять, используя свои ключевые технологии: HTML, HTTP и URI (то же самое, что и URL, для нас сейчас эта разница несущественна).Система «сервер-клиент»
Ключевое условие по Филдингу: сеть должна быть построена на взаимодействии клиентов и серверов. В данном случае сервер — это компьютер, где хранятся востребованные данные, а клиент — компьютер, который стремится воспользоваться хранимыми на сервере ресурсами. Вы входите в интернет, ваш компьютер посылает HTTP-запрос для того чтобы начать пользоваться информацией с сервера. В системе RESTful должна использоваться модель «сервер-клиент», даже если иногда ее отдельные компоненты выступают в обеих ролях одновременно.

Альтернативой данному виду архитектуры следует назвать архитектуру, основанную на управлении событиями (event-based). В такой модели каждый компонент транслирует события непрерывно, пытаясь получать информацию о подходящих для себя событиях от других компонентов. То есть никакого взаимодействия «один на один», только передача и улавливание запросов. Для системы RESTful такой вариант является неприемлемым.

Принцип stateless
Термины stateful и stateless описывают, нужно ли компьютеру или программе устанавливать и запоминать одно или несколько предшествующих событий в последовательности взаимодействия с пользователем, другим компьютером или программой, устройством или внешним элементом. В данном случае stateless означает, что все методы объекта работают вне какого-либо контекста или локального состояния объекта. Клиентам и серверам нет необходимости хранить данные о каждом состоянии друг друга. Если клиент не взаимодействует с сервером, последнему нет нужды знать о состоянии первого. При этом сервер также не хранит информацию о предыдущих запросах. Каждый запрос рассматривается вне контекста, как отдельный.Единый интерфейс
Это условие гарантирует, что и клиент и сервер разговаривают на одном языке, что позволят каждой части быть взаимозаменяемой, ее можно усовершенствовать без прерывания работы всей системы. Это достигается через введение 4 дополнительных условий: распознавание ресурсов, управление ресурсами через образы (или репрезентации), self-descriptive сообщения и гипермедиа.

Параметр интерфейса 1: распознавание ресурсов.


В терминологии REST, источниками (ресурсами) могут выступать HTML документы, изображения, информация о конкретном пользователе и так далее. Каждый из них может распознаваться через заданный идентификатор. «Заданный» в том смысле, что он не меняется в процессе взаимодействия. Он не меняется даже при смене состояния ресурса. Если источник переходит на другой идентификатор, сервер пошлет клиенту информацию о неверном запросе вместе со ссылкой на новое местоположение ресурса.

Web для распознавания источника использует URI и HTTP как типовой протокол взаимодействия. Для размещения источника на сервере клиент делает HTTP GET запрос к URI, который его идентифицирует. Как только вы вводите какой-либо адрес в браузере, он отправляет URI запрос GET. Если последний получает сообщение OK с кодом 200 и HTML-документ, страница отрисовывается на экране.

Параметр интерфейса 2: управление ресурсами через представления


Второе дополнительное условие «единого интерфейса» касается вопроса управления ресурсами. Это происходит через отправку клиентом серверу представлений, обычно в виде объекта формата JSON (XML-подобный формат), содержащий информацию о том, что тот хотел бы изменить, исправить или удалить. В системе REST сервер имеет полный контроль над ресурсами и полностью отвечает за любые изменения в них. Если клиент желает что-либо поправить, он отправляет серверу образ того, как все это должно выглядеть. Сервер рассматривает данный запрос в качестве предложения, но по-прежнему сохраняет над страницами исключительный контроль.

Давайте рассмотрим пример с блогами пользователей. Когда пользователь создает новый пост, компьютер дает понять серверу, что его нужно добавить. Для этого он отправляет ему запрос в виде HTTP POST или PUT с его содержанием. Назад компьютер получает ответ с указанием, был ли пост в итоге создан или информацию об ошибке. Если речь идет не об интерфейсе REST, клиент может отправлять конкретные инструкции дальнейших действий. В случае с REST достаточно послать представление того, как должна выглядеть страница поста в окончательном варианте.

Параметр интерфейса 3: self-descriptive сообщения


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

Допустим, пользователь вводит в адресной строке браузера адрес страницы www.example.com. Браузер отправляет следующий HTTP-запрос:

GET / HTTP/1.1
Host: www.example.com

Это сообщение содержит всю необходимую и достаточную информацию: мы используем метод HTTP и протокол HTTP 1.1.

Сервер может прислать следующий ответ на подобный запрос:

HTTP/1.1 200 OK
Content-Type: text/html



  
    Home Page
  
  











    
Hello World!


Это сообщение также отвечает признакам self-descriptive. Оно говорит пользователю, как следует понимать сообщение, определяя тип содержания как text/html. У пользователя есть вся информация, чтобы разобраться в сообщении правильно.

Представим иной вариант, при котором сервер в первом сообщении присылал бы бинарный код, а в последующих объяснял бы клиенту, как его следует воспринимать — как образ или как фрагмент кода. Если порядок сообщений по каким-либо причинам перепутан, расшифровать его будет весьма затруднительно.

Параметр интерфейса 4: гипермедиа


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

HTML — один из вариантов гипермедиа. Чтобы в этом разобраться, давайте еще раз взглянем на ответ сервера, приведенный выше. сообщает клиенту, что получить картинку страницы можно, отправив GET на адрес www.example.com/awesome-pic.jpg.

Итак «единый интерфейс» означает, что соблюдены все приведенные выше условия: идентификаторы имеются для каждой страницы, ресурсами можно управлять через обмен образами между сервером и клиентом, сообщения отвечают принципу self-descriptive и состоят из гипермедиа. Это, пожалуй, самый важный атрибут системы RESTful, позволяющий пользователям правильно и вовремя реагировать на изменения. Сервер может скорректировать основную реализацию, не прерывая взаимодействие со всеми клиентами, потому что каждое такое взаимодействие автономно. Идентификаторы в таком случае не изменяются, а гипермедиа дает клиентам сведения о процессах, которые необходимо произвести в дальнейшем. Сервер не обязан хранить всю информацию о клиенте и прилагать дополнительные усилия, чтобы ему угодить. И наоборот.

Другие условия Филдинга: кэширование, многослойная система, кодировка по запросу


Первое условие касается необходимости того, что ответы сервера должны быть помечены как кэшируемые и не кэшируемые. Кэширование возникает в случае, когда клиент сохраняет предыдущие ответы сервера. Таким образом, если эта информация потребуется вновь, тот же самый путь можно проделать, основываясь на уже сохраненных данных. Возможность кэширования определяется наличием self-descriptive сообщений, так как, у клиента есть гарантия, что все важные сведения содержатся в одном ответе. Исключается фактор случайности при кэшировании лишь части сообщения.

Многоуровневая «слоеная» система означает, что помимо клиента и сервера во взаимодействии могут принимать участие другие компоненты. То есть в системе может быть больше одного слоя. Но при этом каждый компонент может взаимодействовать лишь с ближайшим к нему слоем. Таким дополнительным компонентом может быть прокси, он передает HTTP-запросы серверам или другим прокси. Это может быть полезно для распределения загрузки и проверки безопасности. Прокси выступает в роли сервера для привязанного к нему клиента, когда тот отправляет запрос, и в качестве клиента, когда транслирует его серверу.

Другой дополнительный компонент — gateway, переводящий HTTP-запрос в другой протокол, передает его, и затем, переводит ответ обратно в HTTP. Клиент может распознавать его как стандартный сервер. Вариант применения gateway — когда системе нужно скачать файл с FTP-сервера.

Кодировка по запросу — единственное необязательное условие во всей этой истории. Оно заключается в возможности сервера отправлять клиенту выполнимый код. Это то, что можно наблюдать на примере метки