[Перевод] Что такое RESTful на самом деле
А ваше приложение — RESTful? Чтобы ответить на этот вопрос нужно сначала разобраться что такое RESTful. Бытует мнение, что отдавать правильные коды ответов в HTTP — это уже RESTful. Или делать правильные идемпотентные HTTP-запросы — это вообще очень RESTful. Мы в Хекслете сделали практический курс по протоколу HTTP (отличия версий, отправка форм, аутентификация, куки и пр.), и в нем мы стараемся рассказать о правильном использовании запросов, но нужно понимать, что RESTful это не про HTTP, это вообще не про протоколы интернета. Современный веб и взаимодействие между браузером и сервером с помощью HTTP и URI могут удовлетворять принципам RESTful, а могут и не удовлетворять.
В сегодняшнем переводе — простое и понятное описание RESTful, и какой должна быть система, чтобы ее можно было так называть.
Если вы занимаетесь веб-разработкой, вы скорее всего слышали о REST. Но если вы такой же как я, то обычно вы притворяетесь и вежливо киваете когда у вас спрашивают, делаете ли вы все RESTful. Я использую HTTP, эээ, значит — это RESTful, так? Недавно я решил наконец выяснить, что означает это модное словечко, которое звучит так умиротворяюще («restful» с англ. «успокоительный», «спокойный»).
Что такое REST?
REST — это аббревиатура от Representational State Transfer («передача состояния представления»). Это согласованный набор архитектурных принципов для создания более масштабируемой и гибкой сети. Эти принципы отвечают на ряд вопросов. Какие у системы компоненты? Как они должны взаимодействовать друг с другом? Как быть уверенным, что можно заменять различные части системы в любое время? Как система может масштабироваться для обслуживания миллиардов пользователей?
Рой Филдинг первым использовал термин REST в 2000 году в своей докторской диссертации «Архитектурные стили и дизайн программных сетевых архитектур». На момент публикации диссертации Всемирная паутина (Web) была уже очень популярна. Филдинг, по существу, шагнул назад и проанализировал черты, которые сделали Web более успешным, чем конкурирующие протоколы Интернета. Затем он выработал концепцию фреймворка для создания сетевой коммуникации, подобной браузеру. Так что REST — это общий набор принципов, характерных не только для Web. Он может быть применен к другим видам сетей, таким как встроенные системы. REST — не протокол, так как он не задаёт деталей реализации.
Ограничения Филдинга
В диссертации Филдинга есть группа архитектурных ограничений, которым должна удовлетворять система, соответствующая требованиям RESTful. Ниже я даю краткий обзор каждого из этих ограничений и рассуждаю как Web удовлетворяет им, на основании его основных технологий: HTTP, HTML, и URI. (Если вы не знакомы с URI, считайте его «URL». Они отличаются, но в нашем обсуждении это не важно). Давайте разберём каждое из ограничений Филдинга.Клиент-сервер
Первое ограничение указывает, что сеть должна состоять из клиентов и серверов. Сервер — это компьютер, который имеет требуемые ресурсы, а клиент — это компьютер, которому нужно взаимодействовать с ресурсами, хранящимися на сервере. Когда вы копаетесь в интернете, ваш компьютер выступает в роли клиента и отправляет HTTP-запросы серверу, чтобы получать доступ к информации и работать с ней. RESTful-система должна производить операции в клиент-серверной модели, даже если компонент периодически ведёт себя то как клиент, то как сервер.
Альтернатива клиент-серверной архитектуре, построенная без REST — это интеграция, основанная на событиях. В этой модели, каждый компонент непрерывно передает события, перехватывая соответствующие события из других компонентов. В ней нет взаимодействия один-к-одному, только передача и перехват. REST требует взаимодействия один-к-одному, поэтому архитектура, основанная на событиях не будет удовлетворять требованиям RESTful.
Отсутствие состояния
Понятие «без состояния» не означает, что серверы и клиенты его не имеют, у них просто нет необходимости отслеживать состояние друг друга. Когда клиент не взаимодействует с сервером, сервер не имеет представления о его существовании. Сервер также не ведёт учет прошлых запросов. Каждый запрос рассматривается как самостоятельный.Единообразие интерфейса
Ограничение гарантирует, что между серверами и клиентами существует общий язык, который позволяет каждой части быть заменяемой или изменяемой, без нарушения целостности системы. Это достигается через 4 субограничения: идентификацию ресурсов, манипуляцию ресурсами через представления, «самодостаточные» сообщения и гипермедиа.1-е ограничение интерфейса: определение ресурсов
Первое субограничение «унифицированного интерфейса» влияет на то, как идентифицируются ресурсы. В терминологии REST что угодно может быть ресурсом — HTML-документ, изображение, информация о конкретном пользователе и т.д. Каждый ресурс должен быть уникально обозначен постоянным идентификатором. «Постоянный» означает, что идентификатор не изменится за время обмена данными, и даже когда изменится состояние ресурса. Если ресурсу присваивается другой идентификатор, сервер должен сообщить клиенту, что запрос был неудачным и дать ссылку на новый адрес.
Web использует URI для идентификации ресурсов, а HTTP — в качестве стандарта коммуникации. Чтобы получить ресурс, хранящийся на сервере, клиент делает к URI HTTP-GET-запрос, который идентифицирует этот ресурс. Каждый раз, когда вы набираете в браузере какой-то адрес, браузер делает GET-запрос на этот URI. Если браузер возвращает 200 OK и HTML-документ обратно, то браузер рендерит страницу в окне, и вы ее видите.
2-е ограничение интерфейса: управление ресурсами через представления
Второе субограничение «унифицированного интерфейса» говорит, что клиент управляет ресурсами, направляя серверу представления, обычно в виде JSON-объекта, содержащего контент, который он хотел бы добавить, удалить или изменить. В REST у сервера полный контроль над ресурсами, и он отвечает за любые изменения. Когда клиент хочет внести изменения в ресурсы, он посылает серверу представление того, каким он видит итоговый ресурс. Сервер принимает запрос как предложение, но за ним всё так же остаётся полный контроль.
Давайте рассмотрим блог в качестве примера. Когда пользователь создаёт новый пост в блоге, его компьютер должен сообщить серверу, что в блог нужно добавить новую запись. Чтобы это выполнить, он посылает HTTP-POST-запрос или PUT-запрос с содержимым в виде новой записи в блоге. Сервер возвращает ответ, указывающий, что запись создана или была проблема. В не-REST мире клиент может в буквальном смысле давать инструкции операциям, вроде «добавить новую строку» и «присвоить записи название», вместо обычной отправки представления того, каким он видит конечный ресурс.
3-е ограничение интерфейса: самодостаточные сообщения
самодостаточные сообщения — это ещё одно ограничение, которое гарантирует унифицированность интерфейса у клиентов и серверов. Только самодостаточное сообщение содержит всю информацию, которая необходима для понимания его получателем. В отдельной документации или другом сообщении не должно быть дополнительной информации.
Чтобы понять, как это касается 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