МИНИСТЕРСТВО НАУКИ И ВЫСШЕГО ОБРАЗОВАНИЯ РОССИЙСКОЙ ФЕДЕРАЦИИ
____________________________
Кафедра ____________________________
РЕФЕРАТ
на тему: «REST API: принципы проектирования и примеры»
Выполнил(а): ____________________________
Группа: ____________________________
Проверил(а): ____________________________
2026
Содержание
- 3
- 6
- 8
- 11
1. Эволюция веб-сервисов и появление REST
К середине 1990-х интернет уже превратился из научной сети в публичную инфраструктуру, но программное обеспечение для обмена данными оставалось архаичным. Разработчикам приходилось связывать корпоративные системы, и в ход шёл протокол RPC (Remote Procedure Call). Идея была проста: вызвать функцию на удалённом сервере так, будто она локальная. Вот только эта простота оборачивалась хрупкостью. Клиент и сервер жёстко привязывались к конкретным языкам программирования и типам данных. Малейшее изменение сигнатуры метода ломало интеграцию, а для каждого нового языка требовался свой адаптер.
Решить проблему совместимости попытался SOAP (Simple Object Access Protocol), стандартизированный консорциумом W3C в 2000 году. Он оборачивал вызовы в XML-конверты и описывал контракты через WSDL. Формально это давало строгость и расширяемость. На практике SOAP превратился в громоздкую машинерию. Каждый запрос требовал сложной обработки заголовков, пространств имён и схем валидации. Для простого действия, вроде получения данных о пользователе, уходило несколько килобайт служебной информации. Масштабирование таких сервисов упиралось в узкие места. Промежуточные прокси и балансировщики нагрузки не могли интерпретировать содержимое XML-конверта, поэтому кэширование и маршрутизация становились нетривиальной задачей. SOAP был надёжен, но медлителен и сложен в отладке.
Параллельно развивался сам HTTP. Изначально, по замыслу Тима Бернерса-Ли в 1989 году, это был протокол для передачи гипертекстовых документов. Он не предполагал вычислений на сервере или сложной бизнес-логики. Но к концу 1990-х инженеры заметили важное свойство: HTTP, универсальный транспортный протокол с богатым набором семантических методов. В отличие от RPC, который использовал HTTP лишь как туннель, можно было задействовать его возможности напрямую. Речь о
кэшировании ответов, условных запросах, идемпотентности операций. Это превращало HTTP из простой трубы для передачи байтов в полноценную платформу для построения распределённых систем.
В 2000 году Рой Филдинг, один из авторов спецификации HTTP/1.1, защитил диссертацию, где описал архитектурный стиль REST (Representational State Transfer). Он не изобретал новые технологии, а обобщил принципы, которые уже сделали Всемирную паутину успешной. Ключевая идея Филдинга заключалась в том, что архитектурный стиль, это не протокол и не библиотека, а набор ограничений. Эти ограничения, такие как единообразие интерфейса, отсутствие состояния на сервере и кэширование, кажутся искусственными рамками. Но именно они позволяют системе масштабироваться горизонтально, выдерживая миллионы запросов без деградации производительности.
Требования к веб-сервисам к началу 2000-х радикально изменились. Монолитные приложения уступали место микросервисам, а количество клиентов росло экспоненциально. Системе требовалась масштабируемость, при которой добавление нового сервера не требовало изменения кода. Нужна была надёжность, позволяющая переживать отказы отдельных узлов. И, что критично, простота интеграции: сторонним разработчикам должно быть достаточно посмотреть на URL и понять, как взаимодействовать с сервисом. SOAP с его сложными контрактами не отвечал этим запросам. REST, напротив, опирался на уже работающую инфраструктуру интернета (DNS, прокси-серверы, кэши). Это снижало порог входа и делало интеграцию делом часов, а не недель.
Архитектурный стиль в понимании Филдинга, это не конкретная реализация, а система координат. Он определяет, как компоненты взаимодействуют друг с другом, какие данные передают и какие свойства обязаны соблюдать. Для REST такими свойствами стали: отсутствие сохранения состояния между запросами, единообразный интерфейс, кэширование ответов, слоистость системы. Каждое из этих
ограничений решает конкретную проблему ранних подходов. Отказ от состояния на сервере упрощает балансировку нагрузки. Единообразие интерфейса делает возможным кэширование на промежуточных узлах. Такой подход оказался настолько жизнеспособным, что сегодня REST де-факто является стандартом для публичных API, вытеснив SOAP в нишу корпоративных систем с высокими требованиями к формальной гарантии контрактов.
2. Ресурсы и их идентификация в REST
Ресурс в REST, это не данные и не база данных. Это любая сущность, информация о которой может быть передана по сети: пользователь, фотография, банковский счёт, текущая погода в городе. В своей диссертации 2000 года Рой Филдинг, автор архитектурного стиля, настаивал на принципиальном отделении ресурса от его представления. Сервер хранит и оперирует ресурсом, а клиент всегда работает только с его конкретной формой. Один и тот же ресурс может быть отдан как JSON, XML, HTML или даже изображение, в зависимости от заголовка Accept в запросе. Такое разделение позволяет одним и тем же данным обслуживать и браузер, и мобильное приложение, и скрипт автоматизации, не меняя логику сервера.
Ключевое свойство ресурса, адресуемость. У каждого ресурса есть уникальный идентификатор, URI (Uniform Resource Identifier), который служит его сетевым адресом. По этому адресу клиент отправляет запросы, и именно он фигурирует в ответах, ссылках и документации. URI, это контракт между сервером и клиентом, поэтому его структура должна быть продумана и стабильна. Изменение URI ломает все существующие интеграции, так что к его проектированию подходят как к долгосрочному обязательству.
Именование ресурсов подчиняется нескольким практическим правилам, выработанным сообществом. Первое: в URI используются существительные во множественном числе, а не глаголы. Вместо `/getUser?id=5` правильно писать `/users/5`. Глаголы вроде `get`, `update`, `delete` не нужны, потому что действие уже заложено в методе HTTP-запроса. Второе правило касается иерархии: URI отражает вложенность сущностей через слэши. Например, `/users/5/orders` показывает, что мы обращаемся к заказам конкретного пользователя, а `/users/5/orders/12`, к конкретному заказу внутри этого списка. Такая структура интуитивно понятна и легко масштабируется. Третье правило,
избегать расширений файлов вроде `.php` или `.aspx` в URI, так как они привязывают адрес к технологии реализации, а не к самой сущности.
Наконец, идентификация ресурса неразрывно связана с методами HTTP, которые определяют допустимые действия над ним. Сам URI не говорит, что с ресурсом можно сделать, он лишь указывает на него. А вот метод запроса задаёт операцию: получение, создание, изменение или удаление. Клиент, зная URI ресурса и выбранный метод, точно понимает, какое действие он инициирует и какой ответ ожидать. Именно это сочетание стабильного адреса и стандартизированных методов превращает REST в предсказуемую и самодокументируемую архитектуру, где клиент и сервер понимают друг друга без лишних согласований.
3. Методы HTTP и статус-коды в REST
Предыдущая глава объясняла, что такое ресурс и как его найти. Теперь речь пойдёт о действиях. HTTP даёт фиксированный набор глаголов, каждый из которых имеет строго определённую семантику. Если использовать их правильно, API превращается из набора эндпоинтов в предсказуемую систему.
Начнём с самого частого метода. GET предназначен для получения данных. Он не должен менять состояние сервера, не должен удалять файлы или увеличивать счётчики. Это правило делает GET безопасным: клиент может повторять запрос сколько угодно раз без побочных эффектов. Идемпотентность здесь очевидна. Десять одинаковых GET-запросов вернут один и тот же результат, если ресурс не изменился по другим причинам. Именно поэтому браузеры и поисковые роботы свободно ходят по ссылкам, не боясь что-то сломать.
Создание новых сущностей ложится на POST. Этот метод не идемпотентен: два одинаковых POST-запроса создадут два разных объекта. Представьте, что клиент отправляет заказ на покупку книги. Повторная отправка того же запроса из-за сетевого сбоя приведёт к дублированию заказа. Разработчики обычно решают эту проблему идемпотентными ключами, но сам протокол такой гарантии не даёт. POST также используют для действий, которые не подходят под остальные методы. Например, для аутентификации или сложных поисковых запросов.
PUT работает иначе. Он заменяет ресурс целиком, и клиент отправляет полное представление объекта. Если ресурса с указанным URI не существует, сервер может его создать. Ключевое свойство PUT, идемпотентность. Отправьте один и тот же PUT-запрос дважды, и состояние системы после первого и второго раза будет идентичным. Это упрощает повторные попытки при обрыве соединения. Частичное обновление выполняет PATCH. Он применяет к ресурсу лишь описанные
изменения, например меняет только поле email у пользователя, не трогая остальные атрибуты. Идемпотентность PATCH не гарантируется: она зависит от формата патча. Операция «увеличить счётчик на единицу» при повторе даст другой результат.
DELETE, как несложно догадаться, удаляет ресурс. Повторный вызов DELETE для уже удалённого объекта обычно возвращает 404 или 204, но состояние системы после второй попытки не меняется. Это делает метод идемпотентным в практическом смысле.
Теперь о том, как сервер сообщает результат операции. Статус-коды HTTP сгруппированы в пять классов. Класс 2xx сигнализирует об успехе. Код 200 означает, что запрос выполнен и тело ответа содержит данные. Для POST, создавшего ресурс, уместен код 201 Created, при этом в заголовке Location указывается URI нового объекта. Если операция прошла успешно, но возвращать нечего, используется 204 No Content. Класс 3xx отвечает за перенаправления. 301 Moved Permanently говорит, что ресурс переехал на новый адрес навсегда, а 304 Not Modified позволяет клиенту использовать закэшированную копию.
Ошибки клиента маркируются классом 4xx. Самый известный код, 400 Bad Request: сервер не понял запрос из-за синтаксической ошибки или некорректных данных. 401 Unauthorized требует аутентификации, а 403 Forbidden запрещает доступ даже после неё. 404 Not Found означает, что ресурс по данному URI не существует. Иногда встречается 409 Conflict: например, попытка создать пользователя с уже занятым email. Класс 5xx сообщает о проблемах на стороне сервера. 500 Internal Server Error, общая ошибка, а 503 Service Unavailable говорит о временной недоступности сервиса, например при перегрузке или техническом обслуживании.
В спецификации HTTP 1.1, описанной в RFC 7231, методы и коды имеют именно такую семантику. Следование ей делает API понятным для любого клиента, знакомого с протоколом. Когда разработчик видит 201, он понимает, что создание прошло
успешно; когда видит 405 Method Not Allowed, понимает, что метод для данного ресурса не поддерживается. Правильный выбор метода и статус-кода, это часть контракта между клиентом и сервером. От его точности зависит, насколько легко будет интегрироваться с вашим API.
4. Практические примеры и обобщение принципов
После разбора теории полезно посмотреть, как принципы REST работают в реальном коде. Возьмём классическую пару сущностей: пользователей и заказы. Для пользователя типичный набор операций выглядит так: создание (POST /api/users), получение списка (GET /api/users), получение одного (GET /api/users/{id}), замена (PUT /api/users/{id}) и удаление (DELETE /api/users/{id}). Обратите внимание: в URI нет глаголов, только существительные. Действие определяется методом HTTP, а не строкой адреса.
Заказы логически вложены в пользователя, поэтому URI строятся иерархически: GET /api/users/{id}/orders возвращает заказы конкретного клиента. Если заказ существует сам по себе, можно использовать плоскую структуру: GET /api/orders/{id}. Выбор зависит от того, является ли заказ самостоятельным ресурсом или только атрибутом пользователя. В большинстве систем заказ ценен сам по себе, поэтому его адресуют напрямую, а вложенный путь оставляют для удобной выборки.
Теперь посмотрим на ответы. Клиент отправляет POST /api/users с телом запроса в JSON. Сервер создаёт запись и возвращает статус 201 Created, а в заголовке Location указывает адрес нового ресурса. Тело ответа содержит полную копию созданного объекта. Это стандарт для REST: клиент не должен угадывать, что произошло, ответ говорит сам за себя. При попытке получить несуществующего пользователя сервер вернёт 404 Not Found с коротким сообщением об ошибке. Если клиент отправит некорректные данные, например пустое поле имени, сервер ответит 400 Bad Request. Если пользователь не авторизован для просмотра заказов, будет 401 Unauthorized. Если прав недостаточно, 403 Forbidden.
Разница между 401 и 403 важна для клиента. Первый означает «представься», второй, «ты известен, но тебе нельзя». Путаница здесь приводит к тому, что фронтенд бесконечно показывает форму логина вместо
сообщения о запрете. Ещё один нюанс: метод PUT требует полной замены ресурса. Если клиент отправляет PUT /api/users/5 только с полем name, сервер должен затереть остальные поля, иначе это нарушает идемпотентность. Для частичного обновления используют PATCH.
Отдельного внимания заслуживает кэширование. Ответ на GET /api/users/5 можно пометить заголовком Cache-Control: max-age=3600. Тогда повторный запрос в течение часа не дойдёт до сервера, а возьмётся из кэша браузера или промежуточного прокси. Это резко снижает нагрузку на инфраструктуру. Но кэшировать POST или DELETE нельзя, они изменяют состояние системы.
Теперь обобщим принципы. Первое: URI содержат только существительные во множественном числе. Второе: каждый метод HTTP имеет строго определённое значение, и его нельзя подменять. Если нужно удалить, используйте DELETE, а не GET с параметром?action=delete. Третье: статус-коды несут семантическую нагрузку. Код 200 означает успех, но если создан новый ресурс, честнее вернуть 201. Четвёртое: версии API указывают в URI или заголовке Accept, например /api/v2/users. Это позволяет менять контракт, не ломая старых клиентов.
И последнее, но критичное: документирование. API без документации бесполезен, даже если код безупречен. Спецификация OpenAPI (ранее Swagger) описывает все ресурсы, методы, параметры и схемы ответов в машиночитаемом формате YAML или JSON. По ней автоматически генерируется интерактивная документация, где разработчик может прямо в браузере отправить тестовый запрос и увидеть ответ. Инструменты вроде Swagger UI или ReDoc превращают спецификацию в удобную страницу. Практика показывает: команда, которая сразу пишет OpenAPI-спецификацию вместе с кодом, тратит меньше времени на согласование интеграций, чем та, что документирует постфактум.
Пример из жизни: в 2020 году компания Stripe опубликовала статистику, что их API обрабатывает миллиарды запросов в день. Ключевым фактором стабильности они назвали строгую спецификацию и идемпотентные ключи для POST-запросов. Это иллюстрирует общее правило: REST хорош не сам по себе, а когда каждый элемент системы следует единому соглашению. Проектирование API, это проектирование контракта между сервером и клиентом. Чем точнее этот контракт описан, тем меньше ошибок на стыке систем.
Нужна такая же работа по своей теме? Соберём структуру, текст и источники в этом же оформлении.