REST — это Representational State Transfer, «передача состояния в виде представлений». Перевод запутывает. Поэтому забудем расшифровку и зайдём с другой стороны: что REST значит на практике для того, кто пишет фронтенд.
Главная идея: всё — ресурс
В мире REST любое данное, с которым работает сервис, называется ресурсом. Конкретный пост в блоге — ресурс. Список всех постов — тоже ресурс. Пользователь с именем «Анна» — ресурс. Корзина с тремя товарами — ресурс. Прогноз погоды в Берлине — ресурс.
У каждого ресурса есть свой адрес — URL. Адрес устроен так, что по нему сразу видно, о чём речь:
https://api.example.com/posts ← все посты
https://api.example.com/posts/42 ← пост с id=42
https://api.example.com/posts/42/comments ← комментарии поста 42
https://api.example.com/users/anna ← пользователь Anna
Это и есть первое практическое правило REST: в URL содержится существительное, а не действие. На /posts/42 можно получить пост, удалить пост или обновить пост — но в URL ничего этого не написано. Что именно сделать с ресурсом — говорит HTTP-метод: GET, POST, PUT, DELETE и другие. Их детальный разбор — в модуле 3.
Поэтому если в каком-то API встречается URL вроде /getPostById?id=42 или /deletePost?id=42, это не очень-то REST. Это просто HTTP-сервис в RPC-стиле, где имя действия зашито в URL. Работать с ним можно, но индустриальный стандарт — именно REST с существительными в адресе.
Безсостояние: сервер ничего о тебе не помнит
Второй ключевой принцип называется statelessness, «безсостояние». Это значит вот что: каждый запрос к серверу должен быть самодостаточным. Сервер не помнит, что вы у него спрашивали минуту назад. Если для ответа нужна авторизация — токен пришлите снова. Если нужен контекст — добавьте его в запрос.
Зачем так? Это позволяет масштабировать сервер: запросы можно раскидать по десяти разным машинам, и каждая обработает любой из них, потому что ничего не нужно «помнить». В мире, где приложения держат миллионы соединений одновременно, это не роскошь, а необходимость.
На практике это значит, что в каждом запросе вы передаёте всё, что нужно серверу для ответа: токен авторизации в заголовке Authorization, параметры фильтрации в URL, тело запроса с данными. Сервер обработал — и забыл.
Единый интерфейс
Третий принцип проще предыдущих: любой ресурс трогается одним и тем же набором операций. Достать данные — всегда GET. Создать — всегда POST. Обновить — всегда PUT или PATCH. Удалить — всегда DELETE.
Это значит, что если научились работать с одним REST API — работа с любым другим уже похожа на 80%. Различия будут только в адресах и форматах данных. Сами операции одни и те же. Это огромная экономия мысли.
JSON для данных
Спецификация REST не требует JSON. В принципе ответ может приходить хоть в XML, хоть в формате собственного изобретения. Но на практике в современном вебе REST API почти всегда говорят на JSON — формате, очень похожем на объекты JavaScript. О нём в следующем модуле отдельная глава.
Откуда взялся REST
Слово REST придумал в 2000 году Рой Филдинг в своей докторской диссертации. Он описал шесть архитектурных ограничений (constraints), которым должен удовлетворять «настоящий» REST: client-server, statelessness, cacheability, uniform interface, layered system, code on demand. Каждое из них имеет смысл и продумано на годы вперёд.
На практике большинство современных API называют себя REST, не соответствуя строгому определению Филдинга по всем пунктам — особенно по HATEOAS (последний принцип про то, что ответы должны содержать ссылки на дальнейшие действия). Это нормально. В индустрии под «REST API» обычно понимают любой HTTP-сервис, где URL построены вокруг существительных-ресурсов, ответы приходят в JSON, методы используются по назначению. Если хочется звучать строго — такие сервисы называют «HTTP API». Но в 95% разговоров эти слова взаимозаменяемы.
Этой 80%-картины достаточно, чтобы быть продуктивным. Глубже про шесть ограничений Филдинга, уровни зрелости Ричардсона и HATEOAS — можно прочитать после того, как фундамент устаканится. Сейчас идём дальше.