Как говорится, в споре рождается истина. И этот случай не стал исключением. Часто проектирую запросы, консультирую аналитиков, сама консультируюсь у разработчиков и заметила, что иногда мы по-разному понимаем некоторые аспекты REST. Когда я стала погружаться в тему, то материала набралось столько, что одной статьей не обойтись. Понимание мифов позволяет делать более осознанный выбор при проектировании.
С вами Дарья Борисова, системный аналитик из ПСБ, и я начинаю цикл статей «Мифы о REST».
Миф 1: REST — это синоним HTTP JSON API.

Да, с таким утверждением всё ещё иногда сталкиваюсь при общении с аналитиками, поэтому хочется расставить все точки над i.
Реальность:
REST — это абстрактный архитектурный стиль, который можно реализовать поверх разных протоколов. HTTP — лишь самый популярный из них. JSON — всего лишь один из возможных форматов данных, наравне с XML, HTML, YAML и даже простым текстом.
Объяснение:
Огромное количество API, которые называют себя RESTful, на самом деле являются просто HTTP API, использующими JSON. Они часто нарушают ключевые принципы REST, такие как единообразие интерфейса или использование гипермедиа (HATEOAS). Для определения «насколько RESTful ваш API», можно использовать модель зрелости Ричардсона. Это не официальный стандарт, но полезный инструмент:
Уровень 0: Болото POX
Почему «болото»? Потому что здесь нет структуры, присущей вебу. Принцип взаимодействия напоминает удаленный вызов процедур. Все взаимодействие строится вокруг отправки команд на один «универсальный» URL (чаще всего методом POST). Сервер смотрит внутрь тела запроса, чтобы понять, что с ним делать дальше.
Уровень 1: Ресурсы (есть понятие уникальных URI)
На этом уровне появляется ключевая концепция REST — ресурсы. Каждый ресурс имеет свой уникальный адрес. API становится более структурированным и понятным. Легче увидеть, с какими данными мы работаем. По-прежнему используется, как правило, только один HTTP-метод (чаще POST).
Пример
Чтобы получить данные о пользователе:
POST /users/get
Чтобы создать заказ:
POST /orders/create
Уровень 2: HTTP-глаголы
Это самый распространенный уровень для современных "RESTful" API. Здесь используется вся мощь протокола HTTP (методы GET, POST, PUT, DELETE, PATCH и т.д.) для выполнения операций над ресурсами. Также начинают использоваться HTTP-коды статусов для информирования клиента о результате. Усовершенствована семантика (Значение запроса ясно из пути к методу), вводится понятие идемпотентности методов.
Уровень 3: HATEOAS — только здесь мы получаем«настоящий» REST по Филдингу
Ответы сервера содержат не только данные, но и гипермедиа‑ссылки, которые указывают на возможные следующие действия клиента.
Считается, что клиент не должен «знать» или «строить» URI для следующих шагов. Он начинает с одной точкой входа (например, корневой URL API) и затем «переходит» по ссылкам, которые сервер предоставляет в своих ответах. Состояние приложения управляется этими ссылками.
Появляется независимость клиента и сервера. Сервер может менять свои URI, не ломая клиенты, так как клиенты используют URI‑ссылки, а не «зашитые» в коде URL.
API становится самоописываемым. Клиент может «исследовать» API динамически, подобно тому как человек исследует веб-страницу, переходя по ссылкам.
6 ограничений REST
6 ограничений REST из диссертации Филдинга:
Клиент-Сервер
Система должна быть разделена на тех, кто предоставляет ресурсы и управляет данными (сервер), и тех, кто потребляет ресурсы (клиент).
Stateless
Каждый запрос от клиента к серверу должен содержать всю информацию, необходимую для его понимания и обработки. Сервер не должен хранить какое-либо состояние сессии между запросами.
Кэширование
Ответы сервера должны быть явно или неявно помечены как кэшируемые или нет. Если ответ кэшируем, клиент имеет право повторно использовать данные из ответа для последующих эквивалентных запросов.
Единообразие интерфейса
Каждый ресурс (объект, сущность) в системе должен быть однозначно идентифицирован через URI (Uniform Resource Identifier). Например, /books/123
– Слоистая система
Архитектура может состоять из множества слоев. Клиент не может и не должен знать, подключен ли он напрямую к конечному серверу или через промежуточные посредники (прокси, шлюзы). Разделение на слои помогает разделить ответственность между слоями: кэширование, безопасность, балансировку нагрузки.
Код по требованию
Клиент взаимодействует с приложением исключительно через гипермедиа (ссылки), динамически предоставляемые сервером в ответах. Клиент не должен «знать» или «строить» URI. Он начинает с одной точкой входа и «переходит» по ссылкам, которые сервер ему предоставляет.
Большинство популярных API находятся на уровне 2, что не делает их полноценно RESTful, но не мешает им быть практичными и успешными.
Уровень 3 редко используется на практике из‑за своей сложности и меньшей предсказуемости для разработчиков, но он остается идеалом, к которому стоит стремиться для создания максимально гибких и долгоживущих веб‑сервисов.
Миф 2: Чтобы API был RESTful, обязательно нужно использовать гипермедиа.

Я сама ни разу не использовала гипермедиа в своих методах, при этом искренне полагала, что мои методы являются RESTовыми. Оказалось, без этого параметра называться RESTом нельзя. Но это вовсе не значит, что без гипермедиа ничего не будет работать. Просто с формальной точки зрения применять эту классификацию будет некорректно.
Реальность:
Использование HATEOAS является обязательным условием для того, чтобы API соответствовал стилю REST в его изначальном, академическом понимании по Филдингу. Однако для подавляющего большинства современных REST API это условие игнорируется, и они при этом успешно решают свои бизнес‑задачи.
Объяснение:
HATEOAS означает, что клиент взаимодействует с API исключительно через гиперссылки, предоставляемые самим API. Клиент не должен «знать» или «конструировать» URL‑адреса. Он начинает с одной точки входа (например, /api), а дальше каждое ответ сервера содержит не только данные, но и ссылки на возможные следующие действия.
Рой Филдинг неоднократно заявлял, что если в API нет HATEOAS, то его нельзя называть RESTful. Это не вопрос мнения, а соблюдение формального определения. Без HATEOAS клиент и сервер тесно связаны через знания о структуре URL. Если на сервере изменится путь к ресурсу, все клиенты, которые «захардкодили» старый URL, сломаются. В случае с HATEOAS клиент всегда использует URL из поля self или _links, и изменения на сервере для него не страшны.
Несмотря на строгое определение, в индустрии сложилась иная практика:
Непрактично: Реализация полноценного HATEOAS — это сложная задача как на стороне сервера (нужно генерировать ссылки для каждого контекста), так и на стороне клиента (нужно парсить ссылки и динамически строить UI). Для многих задач это избыточно.
99% API, которые называют себя RESTful, на самом деле являются HTTP API или REST‑like. Они используют некоторые принципы REST (ресурсы, HTTP‑методы, коды состояний), но игнорируют HATEOAS. (Если вы активный пользователь гипермедиа, расскажите об этом в комментарии, а то, может быть, цифра «99%» окажется некорректной)
Как решаем:
Проблему хрупкости клиентов из‑за изменений URL успешно решают инструменты наподобие Swagger (OpenAPI). Клиентская библиотека (например, сгенерированная по OpenAPI‑спецификации) знакома со всей структурой API, и при ее изменении клиент просто генерируется заново. Это проще, чем реализовывать логику обработки гипермедиа.
Миф 3: REST не подходит для высоконагруженных или real-time систем.

Обычно, если слышим real-time, ментально сразу отказываемся от REST. А может, не стоит? А может, договоримся? :)
Реальность:
Это утверждение является сильным упрощением и, по большей части, заблуждением. REST сам по себе не является узким местом производительности. Проблемы в высоконагруженных или real-time сценариях возникают не из-за архитектурного стиля REST, а из-за неправильного выбора или настройки транспортного механизма (чаще всего, HTTP/1.1), неоптимального дизайна API и игнорирования возможностей современных протоколов. Крупнейшие высоконагруженные системы в мире (Google, Amazon, Twitter) активно используют RESTful API.
Объяснение
Чтобы понять, почему миф так живуч, нужно разобрать его на составляющие.
1. Путаница между REST и HTTP/1.1:
REST (Representational State Transfer) — это архитектурный стиль, набор принципов (без состояния, единообразие интерфейса, кэшируемость и так далее). Он не диктует конкретный протокол.
-
На практике REST почти всегда реализуется поверх HTTP. И когда люди говорят о «медленном REST», они обычно имеют в виду ограничения HTTP/1.1:
Отсутствие мультиплексирования: каждый запрос требует отдельного TCP‑соединения (или использует очередь в рамках одного keep‑alive соединения). Это создает большую нагрузку и задержки (latency) при множестве параллельных запросов.
Избыточные заголовки: каждый запрос/ответ передает полный набор HTTP‑заголовков, многие из которых повторяются.
Односторонняя инициатива: клиент всегда должен опрашивать сервер для получения новых данных (polling), что неэффективно для real‑time.
2. «Real‑time» — разный смысл:
• Миф особенно силен в контексте real‑time. Действительно, «классический» REST (запрос‑ответ) плохо подходит для сценариев, где сервер должен немедленно уведомлять клиента о событиях (чаты, биржевые котировки, онлайн‑игры).
• Однако, REST не запрещает использовать другие протоколы поверх своей архитектуры для решения этих задач.
3. Проблемы дизайна API, а не архитектуры:
• N+1 проблема: неудачно спроектированный REST API может заставлять клиента делать десятки дополнительных запросов для получения связанных данных (например, получить список статей, а затем для каждой статьи отдельным запросом — автора).
• Недо‑ или пере‑получение данных: клиент получает либо слишком мало данных (требуются новые запросы), либо слишком много (передача лишних полей), что тратит bandwidth и время на парсинг.
Как решать
Решение заключается не в отказе от REST, а в грамотном применении современных технологий и лучших практик поверх его принципов.
Для высоконагруженных систем:
1. Переход на HTTP/2 и HTTP/3:
HTTP/2 решает ключевые проблемы HTTP/1.1: мультиплексирование (многие запросы в одном TCP‑соединении), приоритизация запросов. Это кардинально снижает задержки и нагрузку.
HTTP/3 еще больше уменьшает latency, решая проблемы блокировки на транспортном уровне.
2. Эффективный дизайн API:
GraphQL как дополнение: для сложных клиентов с часто меняющимися требованиями к данным рассмотрите использование GraphQL поверх REST. GraphQL позволяет клиенту запросить все необходимые данные за один запрос, решая проблемы N+1 и переполучения данных. Бэкенд‑сервисы при этом могут оставаться RESTful.
RESTful с гибкими конечными точками: если оставаться в парадигме REST, используйте параметры запроса для выбора возвращаемых полей в ответе.
Для Real‑Time систем:
1. WebSockets поверх REST‑архитектуры:
Это самый популярный и эффективный способ. Ваше приложение остается RESTful для CRUD‑операций (создать чат, получить историю сообщений), а для реального времени используется отдельное WebSocket‑соединение.
Клиент устанавливает постоянное двустороннее соединение с сервером через WebSocket. Сервер может мгновенно «протолкнуть» (push) данные клиенту, как только они появятся.
2. Server‑Sent Events (SSE):
Более простая альтернатива WebSockets, когда нужно только однонаправленное движение данных от сервера к клиенту (например, лента новостей, уведомления, мониторинг).
Работает поверх стандартного HTTP, что упрощает интеграцию с существующей инфраструктурой. Клиент просто «подписывается» на поток событий с сервера.
3. Long Polling:
Хотя это не истинный real‑time, это надежный fallback‑механизм, который хорошо работает поверх REST. Клиент делает запрос, сервер «висит» на нем, пока не появится новое событие или не истечет таймаут. После этого клиент сразу делает новый запрос. Самый распространенный пример использования механизма — уведомления.
Эффективнее, чем постоянный polling с короткими интервалами.
Миф 4. Все endpoint'ы должны возвращать JSON. XML мертв.

Один из популярных вопросов на собеседованиях: «Может ли REST возвращать XML?» Может. А вот в каких случаях может быть полезен теговый монстр, сейчас разберем.
Реальность
Это утверждение является сильным упрощением и не отражает реального положения дел в индустрии. JSON, безусловно, доминирует в сфере публичных RESTful API и веб‑разработки, особенно в контексте взаимодействия Frontend и Backend. Однако XML далек от смерти и продолжает активно использоваться в критически важных областях, где его особенности дают существенные преимущества. Правило «один формат на все случаи жизни» — это плохая архитектура.
Объяснение
Давайте разберем, почему миф так популярен, и где он рассыпается при столкновении с реальностью.
Почему JSON стал таким популярным:
Простота и читаемость: синтаксис JSON легче для понимания человеком и проще в парсинге, чем XML.
Идеальная интеграция с JavaScript: является нативным форматом для JS, что сделало его незаменимым в современной веб‑разработке.
Меньший overhead: в среднем, JSON‑документы менее объемны, чем аналогичные XML, из‑за отсутствия закрывающих тегов.
Быстрота парсинга: парсеры JSON обычно быстрее других и при этом требуют меньше ресурсов.
Почему XML не мертв и все еще актуален:
Стандарты и строгая типизация (XSD, WSDL): XML Schema (XSD) позволяет создавать строго типизированные и валидируемые контракты данных. Это критически важно в корпоративных (Enterprise) и финансовых системах, где недопустима ошибка в формате данных. WSDL для SOAP‑сервисов до сих пор является стандартом де‑факто для многих интеграций между крупными системами.
Пространства имен (Namespaces): XML предоставляет мощный механизм пространств имен, который позволяет смешивать словари из разных стандартов в одном документе без конфликтов. Это используется в таких сложных стандартах, как SAML (безопасность), SOAP, SVG.
Богатые возможности трансформации (XSLT): XSLT — это язык для преобразования XML‑документов в другие форматы (HTML, другой XML, plain text). Это мощный инструмент для декларативного описания преобразований данных.
Сложные структуры и аннотации: XML лучше справляется с представлением сложных, иерархических документов со смешанным (mixed) содержимым (текст + элементы) и атрибутами. Например, документы в юриспруденции, медицинские записи, техническая документация.
Устоявшаяся экосистема: огромное количество legacy‑систем в банковском секторе, телекоммуникациях, государственных учреждениях построено на XML/SOAP. Их переписывание стоило бы миллиарды и при этом не было бы оправдано.
Вывод по объяснению:
JSON — это «быстрый и удобный» формат для большинства веб‑сценариев.
XML — это «строгий и мощный» формат для сложных enterprise‑интеграций, где важна гарантированная структура, валидация и безопасность.
Они решают разные задачи.
Как решать
Вместо следования догме «только JSON», принимайте архитектурные решения, исходя из контекста.
1. Определяйте контекст использования API
Публичное API для мобильных и веб‑приложений? Однозначно JSON. Это стандарт де‑факто.
Внутренняя интеграция с современными микросервисами? Скорее всего, JSON.
Интеграция с банковской системой, государственным порталом или корпоративной ERP (например, SAP)? Высока вероятность, что вам потребуется поддержка XML/SOAP.
Система, работающая с документами (например, генерация отчетов, конвертация данных)? Рассмотрите XML/XSLT, если преобразования сложные.
2. Используйте согласование содержимого
Это правильный HTTP‑способ поддержки нескольких форматов. Клиент сообщает серверу, какие форматы он понимает, с помощью заголовка Accept. Сервер, в зависимости от этого заголовка, возвращает данные в нужном формате, а также указывает его в Content‑Type.
Практическая реализация: Большинство современных фреймворков (Spring в Java, ASP.NET Core, Express.js с middleware) позволяют легко реализовать эту логику. Вы пишете один метод контроллера, который возвращает объект, а фреймворк или специальный конвертер автоматически сериализует его в JSON или XML на основе заголовка Accept.
3. Следуйте принципу «API First»
Проектируйте ваше API, начиная с контракта. Если вы решили, что вашему API нужен и JSON, и XML, опишите его контракты (например, с помощью OpenAPI для JSON и XSD для XML). Это поможет избежать несоответствий.
4. Не смешивайте форматы без необходимости:
Если ваша аудитория — исключительно веб‑разработчики, и у вас нет требований к интеграции с legacy‑системами, нет смысла добавлять XML «на всякий случай». Это усложнит код и тестирование. Используйте тот формат, который наилучшим образом соответствует потребностям ваших клиентов.
Вывод:
Утверждение «XML мертв» — это миф, рожденный в специфическом контексте веб‑разработки. Реальность такова, что JSON и XML сосуществуют, обслуживая разные ниши. Хороший инженер выбирает инструмент под задачу, а не следует модным лозунгам.
Заключение
REST — это не догма, а набор руководящих принципов.
Нарушение некоторых принципов (например, HATEOAS) часто является осознанным и практичным решением.
Цель — не достичь 100% чистоты REST, а создать понятное, масштабируемое и надежное API.
Понимание мифов позволяет делать более осознанный выбор при проектировании.
А с какими мифами о REST сталкивались вы? Делитесь в комментариях!
В следующей статье цикла планирую рассмотреть мифы:
PUT и PATCH — это почти одно и то же, можно использовать любой.
REST API не может иметь состояния (stateless) — значит, нельзя использовать сессии.
И ещё парочку «секретных» мифов :)
Подписывайтесь на блог, чтобы не пропустить!
Комментарии (5)

Rsa97
16.12.2025 07:01Стандартные вопросы:
HTTP - транспорт для REST или его неотъемлемая часть?
Что делать, если HTTP-статусов не хватает? Как различить по ошибке 404 отсутствие конкретного ресурса (ошибка уровня приложения) и отсутствие обработчика API (ошибка уровня транспорта)? Добавлять информацию в ответ? Но зачем тогда вообще использовать HTTP-статусы?
Что делать если HTTP-глаголов не хватает? Создавать псевдоресурсы?
Что делать, если нужен REST over WebSocket? Там нет ни глаголов, ни статусов, ни синхронных ответов.
daskuncik Автор
16.12.2025 07:01Один комментарий, а сколько интересного! :)
HTTP - это все же транспорт. RESTful API может использовать и другие протоколы передачи, просто HTTP больше всех поддерживает базовые принципы REST, поэтому его используют в связке с REST чаще всего.
Про HTTP-статусы:
1. При проектировании API не использую в качестве ответа код 404, его оставляю все-таки как транспортную ошибку. когда хочу проиллюстрировать пользовательскую ошибку в данных, беру HTTP-код 400, а в теле делаю 2 поля: error_code, error_description. Решение в лоб, но рабочее. Для прав доступа есть код 403.2. Можно добавить специальные поля в HTTP-заголовки ответа, где явно показывать источник ошибки: endpoint или resource.
В идеале можно скомбинировать оба способа для удобства дальнейшей классификации, если видов ошибок достаточно много
Про HTTP-глаголы:
могу ответить кратко, а могу включить этот вопрос в одну из следующих статей, где рассмотрю это подробно. что выберете? :)
apevzner
Интересно, в какой степени можно утверждать, что IPP (Internet Printing Protocol, RFC8010, RFC8011) - это RESTFul протокол?
daskuncik Автор
Спасибо за интересный вопрос.
IPP соблюдает большинство принципов REST (клиент-серверный, без состояний, кешируемый, манипулирует ресурсами через представления GET, POST и тд), но не поддерживает HATEOAS. А в статье мы как раз говорили о том, что если придерживаться формальных определений, то без гипермедиа REST'ом называться нельзя. Но мы ориентируемся на практику, где 99% методов не используют гипермедиа и претендуют на звание REST-like. Поэтому и для IPP предлагаю использовать звание REST-like. :)
apevzner
В большинстве случаев, поддерживает (если я правильно понимаю, что такое HATEOAS).
Вы начинаете с URL, который представляет принтер. Когда вы создаёте Job, вы получаете URL этого Job-а, и т.д.
Состояние у IPP есть, но это не искусственная сессия, а состояние реальных дел. Например, пока принтер пережёвывает задание на печать (процесс вдумчивый и не быстрый, механика же), то состояние задания становится частью состояния принтера.