REST API на реальных примерах: от теории к практике

Практический курс, раскрывающий принципы работы REST API через разбор жизненных сценариев и технических кейсов. Вы научитесь понимать архитектуру веб-сервисов, правильно использовать HTTP-методы и проектировать удобные интерфейсы.

1. Введение в REST: архитектурный стиль и взаимодействие клиента с сервером

Введение в REST: архитектурный стиль и взаимодействие клиента с сервером

Добро пожаловать в курс «REST API на реальных примерах». Если вы когда-либо задумывались, как мобильное приложение узнает погоду, как Instagram загружает новые фото или как интернет-магазин обрабатывает ваш заказ, то вы пришли по адресу. За всей этой «магией» стоит четкая система взаимодействия, и чаще всего это — REST API.

В этой первой статье мы не будем писать сложный код. Наша цель — понять философию, архитектуру и основные принципы, благодаря которым работает современный интернет.

Невидимые официанты интернета

Представьте, что вы пришли в ресторан. Вы (клиент) сидите за столиком и хотите заказать суп. На кухне (сервер) есть все ингредиенты и повара, которые умеют этот суп готовить. Но вы не идете на кухню сами, чтобы нарезать овощи и стоять у плиты. И повар не бегает в зал к каждому столику, чтобы узнать, что приготовить.

Между вами есть посредник — официант. Вы даете официанту заказ (запрос) в понятном формате (по меню), официант относит его на кухню, а затем приносит вам готовое блюдо (ответ).

В мире программирования: * Клиент — это ваше приложение (браузер, мобильная игра, умные часы). * Сервер — это мощный компьютер где-то в дата-центре, который хранит данные и логику. * API — это тот самый официант.

!Аналогия ресторана: Клиент, API (официант) и Сервер (кухня)

Что такое API?

Аббревиатура API расшифровывается как Application Programming Interface (программный интерфейс приложения). Это набор правил, по которым одна программа может обратиться к другой.

API — это контракт. Если вы нажмете кнопку «Оплатить» в приложении, приложение точно знает, какое сообщение отправить серверу банка, чтобы деньги списались. Если сообщение составлено неверно (нарушен контракт), сервер его отвергнет.

Что такое REST?

Теперь добавим слово REST. Это акроним от Representational State Transfer (передача состояния представления). Звучит сложно и академично, но на практике все проще.

REST — это не библиотека, которую можно скачать, и не строгий протокол. Это архитектурный стиль. Это набор рекомендаций и принципов, как правильно организовать взаимодействие между клиентом и сервером, чтобы система была простой, масштабируемой и надежной.

> REST — это стиль архитектуры программного обеспечения для распределенных гипермедиа-систем, таких как Всемирная паутина. > — Рой Филдинг, автор концепции REST

Если API построен по принципам REST, его называют RESTful API.

Архитектура Клиент-Сервер

Фундамент REST — это разделение ответственности. Взаимодействие всегда происходит между двумя сторонами:

  • Клиент (Client): Инициатор общения. Он отправляет запрос. Клиента не волнует, как именно сервер ищет данные в базе или как он их обрабатывает. Главное для клиента — получить результат и красиво отобразить его пользователю.
  • Сервер (Server): Тот, кто отвечает. Он хранит данные, обеспечивает безопасность и бизнес-логику. Серверу абсолютно все равно, кто к нему обращается: iPhone, Android, веб-сайт или умный холодильник. Его задача — принять запрос, проверить права доступа, выполнить действие и вернуть данные.
  • Такое разделение позволяет разрабатывать клиентскую и серверную части независимо друг от друга. Пока бэкенд-разработчики оптимизируют базу данных, фронтенд-разработчики могут перерисовывать дизайн кнопок.

    Ключевые принципы REST

    Чтобы ваш сервис мог гордо называться RESTful, он должен соблюдать несколько важных принципов. Давайте разберем самые главные из них на реальных примерах.

    1. Отсутствие состояния (Stateless)

    Это, пожалуй, самый важный и сложный для понимания принцип. Stateless означает, что сервер не запоминает состояние клиента между запросами.

    Вернемся к аналогии с рестораном. Представьте, что у официанта (сервера) полная амнезия. Вы подзываете его и говорите: «Принесите мне еще кофе». В обычном ресторане официант помнит, что вы заказывали ранее. Но в REST-ресторане официант посмотрит на вас с недоумением: «Кто вы? Какой кофе? Вы уже что-то заказывали?».

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

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

    2. Единообразие интерфейса (Uniform Interface)

    Взаимодействие должно быть стандартизировано. Неважно, запрашиваете вы данные о пользователях, товарах или котиках — способ обращения должен быть похожим.

    В REST мы оперируем Ресурсами. Ресурс — это любой объект данных: статья, пользователь, товар, заказ. У каждого ресурса есть уникальный адрес (URI). Например:

    * https://api.shop.com/products — список всех товаров. * https://api.shop.com/products/123 — товар с ID 123. * https://api.shop.com/users/45 — пользователь с ID 45.

    Мы не придумываем уникальные названия действий вроде getProductById или deleteUserNow. Мы используем стандартные методы протокола HTTP (GET, POST, PUT, DELETE), о которых подробно поговорим в следующих статьях.

    !Структура URI в REST: от сервера к конкретному ресурсу

    3. Кэшируемость (Cacheability)

    Данные в интернете передаются не мгновенно. Чтобы ускорить работу, REST поощряет кэширование. Сервер может пометить свой ответ как «кэшируемый».

    Например, список городов страны меняется крайне редко. Сервер может сказать клиенту: «Вот список городов, запомни его и не спрашивай меня об этом ближайшие 24 часа». Клиент сохранит данные у себя и в следующий раз возьмет их из памяти, не нагружая сеть и сервер.

    Реальный пример: Интернет-магазин книг

    Давайте соберем все вместе на примере API книжного магазина.

  • Клиент (Ваш браузер) хочет показать вам книгу «Гарри Поттер».
  • Клиент формирует запрос к ресурсу: GET /books/harry-potter.
  • Запрос летит на сервер. В нем есть вся информация: кто спрашивает и что нужно.
  • Сервер получает запрос, находит книгу в базе данных.
  • Сервер формирует ответ. Обычно это данные в формате JSON (текстовый формат, понятный машинам).
  • Сервер отправляет ответ обратно. В ответе также указано, можно ли кэшировать эту информацию.
  • Клиент получает JSON и рисует красивую карточку товара с обложкой и ценой.
  • Пример того, как сервер отвечает клиенту (формат JSON).

    Почему REST победил?

    Существуют и другие способы общения программ (например, SOAP или GraphQL), но REST остается самым популярным стандартом для веб-сервисов. Причины просты:

    * Простота: Он использует тот же протокол HTTP, на котором работает весь интернет. * Гибкость: Клиент и сервер могут развиваться независимо. * Читаемость: Адреса ресурсов интуитивно понятны человеку.

    В следующей статье мы углубимся в технические детали: разберем структуру HTTP-запроса, узнаем, чем GET отличается от POST, и научимся читать коды ответов сервера.

    Готовы переходить от теории к практике? Тогда до встречи в следующем уроке!

    2. HTTP-методы в действии: разбор операций CRUD на примере управления пользователями

    HTTP-методы в действии: разбор операций CRUD на примере управления пользователями

    В предыдущей статье мы сравнили REST API с официантом в ресторане. Вы узнали, что клиент делает заказ, а сервер его выполняет. Но как именно клиент объясняет официанту, что он хочет сделать? Хочет ли он просто посмотреть меню, заказать новое блюдо, заменить ингредиент в салате или отменить заказ?

    В протоколе HTTP, на котором базируется REST, для этого существуют специальные глаголы — HTTP-методы. Именно они определяют характер действия, которое мы хотим совершить над ресурсом.

    Сегодня мы разберем «великолепную четверку» методов, на которых держится весь современный веб, и увидим, как они реализуют концепцию CRUD.

    Что такое CRUD?

    Прежде чем нырять в технические детали HTTP, давайте разберемся с аббревиатурой, которую вы будете слышать на протяжении всей карьеры разработчика — CRUD. Это акроним, описывающий четыре базовые функции, необходимые для работы с любыми данными (будь то пользователи, товары, комментарии или задачи в календаре).

    Расшифровывается это так:

  • Create (Создание) — добавить новую запись.
  • Read (Чтение) — получить информацию о записи или список записей.
  • Update (Обновление) — изменить существующую запись.
  • Delete (Удаление) — удалить запись.
  • В REST API каждой из этих операций соответствует свой HTTP-метод. Это делает интерфейс предсказуемым и понятным.

    !Наглядное сопоставление операций CRUD и методов HTTP

    Давайте рассмотрим каждый метод на практике, создавая систему управления пользователями для вымышленного приложения.

    GET: Только спросить

    Метод GET используется для чтения данных (буква R в CRUD). Это самый частый запрос в интернете. Когда вы открываете любую страницу в браузере, он отправляет GET-запрос серверу.

    Ключевая особенность: GET-запросы должны быть безопасными. Это значит, что они не должны менять состояние сервера. Вы можете запрашивать список пользователей хоть миллион раз — от этого в базе данных ничего не должно удалиться или создаться.

    Сценарий 1: Получение списка всех пользователей

    Представьте, что администратор хочет увидеть всех зарегистрированных юзеров.

    Запрос клиента:

    Обратите внимание: у GET-запроса обычно нет «тела» (body). Мы просто обращаемся по адресу ресурса.

    Ответ сервера: Сервер возвращает статус 200 OK и список в формате JSON.

    Сценарий 2: Получение конкретного пользователя

    Если нам нужен только один пользователь, мы указываем его уникальный идентификатор (ID) прямо в URL.

    Запрос: GET /users/1

    Ответ:

    POST: Рождение ресурса

    Метод POST используется для создания новых ресурсов (буква C в CRUD). В отличие от GET, здесь мы отправляем данные на сервер, чтобы он их сохранил.

    Сценарий 3: Регистрация нового пользователя

    Мы хотим добавить в систему пользователя «Иван». Мы не знаем, какой ID присвоит ему база данных, поэтому отправляем запрос на общую коллекцию /users.

    Запрос клиента:

    Ответ сервера: Если все прошло успешно, сервер должен вернуть статус 201 Created (Создано). Хорошим тоном считается вернуть в ответе созданный объект уже с присвоенным ID, а также заголовок Location, указывающий, где найти нового пользователя.

    > Важно: POST — это не идемпотентный метод. Если вы случайно отправите один и тот же запрос на создание пользователя дважды, сервер создаст двух Иванов (с разными ID). Поэтому с кнопкой «Отправить» нужно быть осторожным.

    PUT и PATCH: Искусство изменений

    Для обновления данных (буква U в CRUD) используются два метода: PUT и PATCH. Новички часто их путают, но разница между ними принципиальная.

    PUT: Полная замена

    Метод PUT работает по принципу «все или ничего». Он полностью заменяет ресурс по указанному адресу тем, что вы прислали.

    Представьте, что у Ивана изменился email. Если мы используем PUT, мы обязаны прислать полный объект пользователя, даже те поля, которые не менялись (например, имя).

    Запрос:

    Если бы мы прислали только email, а поле name забыли, то после выполнения PUT имя пользователя могло бы стереться (стать null), так как сервер считает: «Раз вы не прислали имя, значит, его больше нет».

    PATCH: Частичное обновление

    Метод PATCH (заплатка) гораздо умнее и экономичнее. Он меняет только те поля, которые вы явно указали.

    Запрос:

    В этом случае сервер найдет пользователя с ID 3, обновит только его почту, а имя и пароль оставит нетронутыми. В современной разработке для редактирования профилей чаще используют именно PATCH.

    DELETE: Удаление

    Метод DELETE отвечает за удаление ресурса (буква D в CRUD). Здесь все просто и сурово.

    Сценарий 4: Удаление пользователя

    Запрос: DELETE /users/3

    Ответ сервера: Обычно сервер отвечает статусом 204 No Content. Это означает: «Все прошло успешно, но мне нечего тебе показать, так как ресурса больше нет».

    Идемпотентность: Сложное слово, простая суть

    В контексте REST API вы часто будете встречать термин идемпотентность. Не пугайтесь, это математическое понятие, которое в программировании означает предсказуемость повторных действий.

    Операция считается идемпотентной, если результат её многократного выполнения идентичен результату однократного выполнения.

    Давайте проверим наши методы:

    * GET (Идемпотентный): Сколько бы раз вы ни запрашивали список пользователей, данные на сервере от этого не меняются. * PUT (Идемпотентный): Если вы 10 раз подряд отправите запрос «Установи имя пользователя = Иван», в итоге имя будет «Иван». Результат такой же, как если бы вы отправили запрос один раз. * DELETE (Идемпотентный): Если вы удалили пользователя, его больше нет. Если вы попытаетесь удалить его снова, ничего не изменится (он все еще удален), хотя сервер может вернуть ошибку 404 во второй раз, состояние системы останется прежним. * POST (НЕ Идемпотентный): Как мы говорили выше, 10 запросов на создание создадут 10 записей. Это меняет состояние системы каждый раз. * PATCH (Обычно НЕ Идемпотентный): Зависит от реализации, но теоретически патч может содержать инструкцию вроде «увеличь возраст на 1». Если выполнить это 10 раз, возраст увеличится на 10 лет.

    | Метод | CRUD Операция | Идемпотентность | Безопасность (Read-only) | | :--- | :--- | :--- | :--- | | GET | Read | Да | Да | | POST | Create | Нет | Нет | | PUT | Update | Да | Нет | | PATCH | Update | Нет* | Нет | | DELETE | Delete | Да | Нет |

    Итоги

    Мы разобрали основные инструменты взаимодействия с REST API. Теперь вы знаете, что:

  • GET — чтобы получить данные.
  • POST — чтобы создать новые данные.
  • PUT — чтобы полностью перезаписать существующие данные.
  • PATCH — чтобы точечно изменить данные.
  • DELETE — чтобы удалить данные.
  • Понимание этих методов — это 50% успеха в проектировании API. Оставшиеся 50% — это правильное использование кодов ответов сервера (те самые 200, 404, 500), о которых мы подробно поговорим в следующей статье. Мы научимся понимать, что именно сервер пытается сказать нам в ответ на наши действия.

    3. Коды состояния и заголовки: как правильно интерпретировать ответы сервера

    Коды состояния и заголовки: как правильно интерпретировать ответы сервера

    В предыдущих статьях мы научились отправлять официанта (API) на кухню (Сервер) с конкретным заказом. Мы разобрали, как использовать методы HTTP (GET, POST, PUT, DELETE), чтобы объяснить, что именно мы хотим сделать: получить меню, заказать суп или отменить десерт.

    Но коммуникация — это двусторонний процесс. Мало просто сказать официанту «Принеси стейк». Важно понять, что он ответит. Принесет ли он стейк? Скажет ли, что мясо закончилось? Или, может быть, сообщит, что кухня сгорела?

    В мире REST API сервер общается с клиентом с помощью кодов состояния (Status Codes) и заголовков (Headers). Понимание этого языка критически важно для разработчика, так как именно эти цифры и метаданные говорят нам об успехе операции или причине провала.

    Коды состояния HTTP: Светофор интернета

    Когда сервер отвечает на ваш запрос, первое, что он сообщает — это трехзначное число. Это и есть код состояния. Он мгновенно дает понять клиенту, как прошел запрос, еще до того, как тот начнет читать тело ответа.

    Все коды состояния разделены на пять классов, определяемых первой цифрой:

    * 1xx (Информационные): «Запрос принят, продолжаю обработку». В реальной разработке REST API встречаются редко. * 2xx (Успех): «Ура! Все прошло хорошо». Операция выполнена успешно. * 3xx (Перенаправление): «Иди туда». Ресурс переехал, и клиенту нужно обратиться по другому адресу. * 4xx (Ошибка клиента): «Ты ошибся». В запросе есть проблема: опечатка, нет прав доступа или такого ресурса не существует. * 5xx (Ошибка сервера): «Я ошибся». Клиент все сделал правильно, но сервер сломался или не может обработать запрос.

    !Визуальное разделение классов кодов состояния HTTP

    Давайте разберем самые популярные коды, с которыми вы будете сталкиваться в 99% случаев.

    2xx: Успешные операции

    Эти коды мы любим больше всего. Они означают, что наша система работает как часы.

    200 OK Самый универсальный ответ. Используется для успешных GET, PUT и PATCH запросов. Это как если бы официант просто поставил перед вами тарелку и сказал: «Пожалуйста».

    201 Created Специфичный ответ для метода POST. Он означает, что ресурс был успешно создан. Сервер говорит: «Я принял ваши данные и создал новую запись в базе». Обычно вместе с этим кодом сервер возвращает заголовок Location со ссылкой на созданный объект.

    204 No Content Идеальный ответ для метода DELETE. Вы попросили удалить пользователя, сервер это сделал. Ему нечего вам возвращать (пользователя-то больше нет), поэтому он говорит: «Успешно, но тела ответа не будет».

    3xx: Перенаправления

    Иногда ресурсы меняют свои адреса (URI). Чтобы не ломать старые ссылки, сервер использует перенаправления.

    301 Moved Permanently «Этот ресурс переехал навсегда». Например, если вы перевели сайт с http на https или изменили структуру каталога товаров. Браузеры и поисковики запоминают этот ответ и в следующий раз сразу идут по новому адресу.

    304 Not Modified Очень важный код для оптимизации. Он работает в связке с кэшированием. Клиент спрашивает: «Есть ли новости?», а сервер отвечает 304: «Ничего не изменилось с твоего последнего визита, используй то, что у тебя уже сохранено в памяти». Это экономит трафик и время.

    4xx: Ошибки на стороне клиента

    Если вы видите код, начинающийся с четверки, значит, проблему нужно искать в вашем запросе (во фронтенде или мобильном приложении).

    400 Bad Request «Плохой запрос». Сервер не понял, чего вы хотите. Чаще всего это синтаксическая ошибка в JSON или нарушение валидации (например, вы пытаетесь зарегистрировать пользователя без email).

    401 Unauthorized «Представьтесь». Сервер не знает, кто вы. Этот код означает ошибку аутентификации. Вы либо не передали токен/пароль, либо он неверен.

    403 Forbidden «Вам сюда нельзя». В отличие от 401, здесь сервер знает, кто вы, но у вас нет прав на это действие. Например, обычный пользователь пытается удалить товар из магазина. Это ошибка авторизации.

    > Запомните разницу: > * 401: «Я тебя не знаю» (нужен логин). > * 403: «Я тебя знаю, но тебе нельзя» (нужны права админа).

    404 Not Found Легендарная ошибка. «Не найдено». Вы запрашиваете ресурс, которого не существует. Либо ID неверен, либо страница удалена.

    429 Too Many Requests «Полегче!». Вы отправляете слишком много запросов за короткое время. Сервер включает защиту от спама или DDoS-атак.

    5xx: Ошибки на стороне сервера

    Это ночной кошмар бэкенд-разработчика. Клиент составил идеальный запрос, но сервер не смог его выполнить.

    500 Internal Server Error «Внутренняя ошибка сервера». Общая ошибка. В коде на сервере произошло необработанное исключение (exception), база данных отключилась или закончилась память. Для клиента это просто сигнал: «Попробуй позже».

    502 Bad Gateway Часто встречается в микросервисной архитектуре. Один сервер (например, Nginx) попытался обратиться к другому (например, вашему приложению на Node.js), но получил некорректный ответ или не смог соединиться.

    503 Service Unavailable «Сервис недоступен». Сервер жив, но перегружен или находится на техническом обслуживании.

    Заголовки HTTP: Паспорт вашего запроса

    Помимо кода состояния и тела ответа (JSON с данными), между клиентом и сервером летают Заголовки (Headers). Это метаданные — информация об информации.

    Представьте конверт с письмом. Письмо внутри — это Body (тело запроса/ответа). А марки, штампы почты, адрес отправителя и пометка «Осторожно, хрупкое» на конверте — это Headers.

    Заголовки представляют собой пары Ключ: Значение. Рассмотрим самые важные из них в контексте REST API.

    Content-Type

    Этот заголовок объясняет получателю, в каком формате пришли данные. В REST API стандартом де-факто является JSON.

    * Запрос: Клиент отправляет Content-Type: application/json, чтобы сервер знал, как парсить пришедший текст. * Ответ: Сервер отвечает тем же заголовком, чтобы браузер или приложение знали, как отобразить ответ.

    Если вы отправите JSON, но забудете этот заголовок, сервер может попытаться прочитать его как обычный текст и выдаст ошибку 400.

    Authorization

    Самый частый способ передать «ключи» от аккаунта. В REST API мы не используем куки (cookies) так часто, как в классических сайтах. Вместо этого мы передаем токен доступа в каждом запросе.

    Пример заголовка: Authorization: Bearer eyJhbGciOiJIUzI1Ni...

    Здесь Bearer — это тип токена (наиболее распространенный), а дальше идет длинная строка самого токена.

    Accept

    С помощью этого заголовка клиент говорит серверу, какой формат ответа он хочет получить. Это называется Content Negotiation (согласование контента).

    Клиент может сказать: Accept: application/json. Если сервер умеет отдавать только XML, он должен вернуть ошибку 406 Not Acceptable.

    Cache-Control

    Этот заголовок управляет кэшированием, о котором мы говорили в первой статье. Сервер может сказать клиенту: Cache-Control: max-age=3600

    Это означает: «Сохрани этот ответ у себя и не беспокой меня по этому поводу следующий час (3600 секунд)».

    User-Agent

    Строка, идентифицирующая клиента. Браузеры пишут туда свои названия (Chrome, Firefox), а мобильные приложения — свои версии. Сервер может использовать это для сбора статистики или для адаптации контента под разные устройства.

    Полный цикл: Как это выглядит в реальности

    Давайте соберем знания из всех трех статей и посмотрим на полный цикл общения.

    Задача: Мы хотим обновить цену книги в магазине.

    1. Запрос Клиента (Request)

    * Метод: PATCH (частичное обновление). * URI: /books/123 (конкретная книга). * Заголовки: Указываем токен доступа и формат данных. * Тело: Новый JSON с ценой.

    2. Обработка на Сервере

    Сервер проверяет токен (валиден), ищет книгу 123 (найдена), проверяет формат JSON (корректен) и обновляет цену в базе данных.

    3. Ответ Сервера (Response)

    * Код: 200 OK (все прошло успешно). * Заголовки: Сервер подтверждает формат данных и ставит дату. * Тело: Возвращает обновленный объект, чтобы клиент мог сразу обновить интерфейс.

    Заключение

    Теперь вы умеете читать мысли сервера. Вы знаете, что 200 — это хорошо, 404 — это «не найдено», а 500 — это повод написать в техподдержку API. Вы понимаете, что заголовки — это не просто служебный мусор, а важные инструкции по обработке данных.

    В следующей части курса мы перейдем к более сложным темам: как проектировать красивые и удобные URL, как делать пагинацию (разбиение на страницы), фильтрацию и сортировку данных, чтобы ваш API был не только рабочим, но и удобным для использования.

    4. Структура данных и ресурсы: проектирование правильных URL и работа с JSON

    Структура данных и ресурсы: проектирование правильных URL и работа с JSON

    Мы уже прошли большой путь. Мы знаем, как «позвать официанта» (HTTP-методы), и понимаем, что он нам отвечает (Коды состояния). Но остается главный вопрос: как правильно назвать блюда в меню, чтобы всем было понятно, о чем речь?

    В REST API «меню» — это ваши URL (адреса ресурсов), а «блюда» — это сами данные, которые чаще всего подаются в формате JSON. Если URL спроектированы хаотично, разработчикам будет больно интегрироваться с вашим сервисом. Если JSON структурирован плохо, приложения будут работать медленно и с ошибками.

    В этой статье мы научимся проектировать красивые, логичные и понятные интерфейсы, которые станут стандартом качества для вашей команды.

    Ресурсы: Фундамент REST

    Вспомним определение из первой статьи: REST работает с Ресурсами. Ресурс — это любая сущность, которой можно дать имя и адрес. Пользователь, товар, комментарий, заказ, настройки — всё это ресурсы.

    Главная ошибка новичков — мыслить действиями (глаголами), а не сущностями (существительными). В старых подходах (например, RPC) мы часто видели такие адреса:

    * POST /createUser * GET /getProducts * POST /deleteOrder

    В REST это считается антипаттерном. Почему? Потому что действие уже заложено в HTTP-методе (POST, GET, DELETE). Дублировать его в URL — это как написать на кнопке «Нажать кнопку».

    Золотое правило №1: Используйте существительные

    URL должен отвечать на вопрос «Что это?», а не «Что сделать?».

    * ~~/getUsers~~ -> /users (Метод GET скажет, что мы хотим их получить) * ~~/deleteProduct~~ -> /products/123 (Метод DELETE скажет, что мы хотим удалить) * ~~/updatePrice~~ -> /products/123 (Метод PATCH с новым ценником в теле запроса)

    !Анатомия правильного RESTful URL

    Золотое правило №2: Множественное число

    Часто возникают споры: использовать /user или /users? В сообществе разработчиков победил стандарт множественного числа.

    Представьте, что /users — это папка с личными делами всех пользователей. Когда вы обращаетесь к ней, вы обращаетесь ко всей коллекции.

    * GET /users — дай мне список всех пользователей из папки. * POST /users — добавь нового пользователя в эту папку. * GET /users/5 — дай мне дело конкретного пользователя под номером 5 из этой папки.

    Использование единственного числа (/user/5) тоже допустимо, но смешивать стили нельзя. Если выбрали множественное — используйте его везде.

    Иерархия и вложенность

    Ресурсы редко живут сами по себе. Обычно они связаны друг с другом. У пользователя есть заказы, у заказов — товары, у товаров — отзывы.

    Как отразить это в URL? Используйте вложенность, но не увлекайтесь.

    Пример: Мы хотим получить список заказов конкретного пользователя (ID=1).

    Логичный путь: GET /users/1/orders

    Здесь мы идем от общего к частному: Пользователи -> Конкретный Иван -> Его заказы.

    А если мы хотим получить конкретный заказ (ID=99) этого пользователя? GET /users/1/orders/99

    Выглядит логично, но тут есть подвох. Если ID заказа (99) уникален в пределах всей системы (а в базах данных обычно так и есть), то нам не обязательно указывать пользователя. Мы можем обратиться напрямую: GET /orders/99

    Совет: Избегайте вложенности глубже 2-3 уровней. URL вида /users/1/posts/5/comments/12/likes слишком сложен для восприятия и поддержки. Лучше разбить его на более плоские структуры.

    Фильтрация, сортировка и пагинация

    Что делать, если нам нужны не все пользователи, а только активные? Или мы хотим отсортировать товары по цене?

    Новички часто создают новые URL: * ~~/getActiveUsers~~ * ~~/usersSortedByPrice~~

    Это неправильно. Ресурс остается тем же — это всё еще список пользователей. Мы просто хотим изменить его представление. Для этого в HTTP существуют Query Parameters (параметры запроса) — то, что пишется после знака вопроса ?.

    Правильные примеры: * Фильтрация: GET /users?status=active * Сортировка: GET /products?sort=price_desc * Поиск: GET /books?q=harry+potter

    Это сохраняет ваш API чистым и предсказуемым. У вас есть один мощный эндпоинт /users, который умеет выдавать данные в разном виде, вместо десятка узкоспециализированных URL.

    JSON: Язык общения

    Мы спроектировали URL, запрос ушел на сервер. В каком формате сервер должен вернуть данные? Сегодня стандартом де-факто является JSON (JavaScript Object Notation).

    Он победил громоздкий XML благодаря своей простоте и читаемости. JSON — это текстовый формат, который легко читают и люди, и машины.

    Структура JSON

    JSON состоит из пар «ключ: значение». Существует два основных типа структур:

  • Объект: Набор пар в фигурных скобках {}.
  • Массив: Список значений в квадратных скобках [].
  • Пример ответа API:

    Правила хорошего тона в JSON

  • CamelCase для ключей: В мире JavaScript и JSON принято называть поля в стиле camelCase (верблюжий регистр): userName, createdAt, isActive. В некоторых языках (Python, Ruby) принят snake_case (user_name), но в JSON лучше придерживаться стандарта JS.
  • Правильные типы данных:
  • * Если это число, не берите его в кавычки: "price": 100, а не "price": "100". Иначе клиент будет вынужден преобразовывать строку в число для математических операций. * Если это булево значение, используйте true/false без кавычек. * Если данных нет, используйте null.
  • Плоская структура: Не делайте JSON слишком глубоким. Чем больше вложенность, тем сложнее клиенту (фронтенду) добираться до данных.
  • Обертка данных (Envelope)

    Часто возникает вопрос: нужно ли возвращать массив сразу или обернуть его в объект?

    Вариант А (Простой массив):

    Вариант Б (Обертка):

    Вариант Б считается более гибким и профессиональным. Почему? Потому что если завтра вы захотите добавить метаданные (например, общее количество товаров для пагинации или время выполнения запроса), в Варианте А вам некуда их вставить, не сломав структуру (массив не имеет именованных полей). В Варианте Б вы просто добавите новое поле рядом с data.

    Версионирование: Думай о будущем

    Рано или поздно ваш API изменится. Вы переименуете поле, удалите старый метод или измените логику работы. Если вы просто обновите код на сервере, приложения пользователей (которые не обновились) перестанут работать.

    Чтобы этого избежать, используйте версионирование.

    Самый простой и наглядный способ — включить версию в URL:

    * https://api.example.com/v1/users * https://api.example.com/v2/users

    Когда вы выпускаете критические изменения, вы создаете версию v2. Старые приложения продолжают работать с v1, а новые переходят на v2. Это гарантирует стабильность бизнеса.

    Практический пример: Блог

    Давайте соберем всё вместе и спроектируем API для простого блога.

    Задача:

  • Получить список статей.
  • Создать новую статью.
  • Получить комментарии к статье.
  • Плохой дизайн (как не надо): * GET /getAllArticles * POST /createArticle * GET /getComments?articleId=5

    Хороший RESTful дизайн:

  • Получить список статей:
  • GET /v1/articles Ответ:

  • Создать статью:
  • POST /v1/articles Тело запроса:

  • Получить комментарии к статье №1:
  • GET /v1/articles/1/comments

    Такая структура интуитивно понятна любому разработчику, который знаком с принципами REST. Она предсказуема, логична и легко расширяется.

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

    5. Инструментарий разработчика: тестирование API через Postman и чтение документации Swagger

    Инструментарий разработчика: тестирование API через Postman и чтение документации Swagger

    Мы прошли долгий путь. Мы разобрали философию REST, выучили язык HTTP-методов, научились понимать коды состояния и спроектировали красивые URL. Но пока что все это происходило у нас в голове или на бумаге. Настало время перейти к настоящей практике.

    Как проверить, работает ли ваш API? Как отправить POST-запрос с JSON-телом, если адресная строка браузера умеет делать только простые GET-запросы? И, самое главное, как понять, какие именно запросы принимает чужой сервер, если вы не писали его код?

    В этой статье мы познакомимся с двумя лучшими друзьями любого бэкенд и фронтенд разработчика: Postman и Swagger.

    Postman: Ваша лаборатория для экспериментов

    Представьте, что вы собрали сложный механизм. Прежде чем встраивать его в автомобиль, вы хотите протестировать его на стенде: подать напряжение, покрутить шестеренки, проверить датчики. В мире API таким стендом является Postman.

    Postman — это инструмент (приложение), который позволяет отправлять HTTP-запросы к сервисам, не написав ни строчки кода. Это графический интерфейс для взаимодействия с API.

    Почему не браузер?

    Браузер — отличный инструмент для серфинга в интернете, но плохой инструмент для разработки API. Когда вы вводите адрес https://api.example.com/users в строку браузера, он всегда отправляет метод GET.

    А как отправить POST с данными регистрации? Как отправить DELETE для удаления? Как добавить специальный заголовок Authorization? Браузер не дает удобных инструментов для этого «из коробки». Postman решает именно эту проблему.

    !Основной интерфейс Postman для создания запросов

    Анатомия запроса в Postman

    Давайте разберем, как собрать запрос, используя знания из предыдущих статей.

  • Выбор метода: Слева от строки адреса есть выпадающий список. Там вы увидите знакомые нам GET, POST, PUT, PATCH, DELETE и множество других экзотических методов.
  • URL: Сюда мы вставляем адрес ресурса. Например: https://jsonplaceholder.typicode.com/posts.
  • Params (Query Parameters): Если вам нужно отфильтровать данные (вспомните ?id=1), вы можете написать это прямо в URL или открыть вкладку Params. Postman предоставит удобную таблицу, где в колонку Key вы напишете userId, а в Value1. Ссылка обновится автоматически.
  • Headers (Заголовки): Здесь мы указываем метаданные. Например, Content-Type: application/json или токен авторизации.
  • Body (Тело запроса): Самая важная вкладка для методов POST и PUT. Здесь мы пишем JSON, который хотим отправить на сервер.
  • > Совет: При выборе тела запроса всегда выбирайте опцию raw, а в выпадающем списке справа — JSON. Это включит подсветку синтаксиса и проверку на ошибки.

    Анализ ответа

    После нажатия большой синей кнопки Send (Отправить), в нижней части экрана появится ответ сервера. Postman раскладывает его по полочкам:

    * Body: Сам ответ (обычно JSON). Postman красиво отформатирует его, добавит отступы и цвета. * Status: Код состояния (например, 200 OK или 404 Not Found). Рядом часто пишется время выполнения запроса (Time) и размер полученных данных (Size). * Headers: Заголовки, которые прислал сервер.

    Коллекции и переменные

    Сила Postman не только в единичных запросах, но и в организации работы.

    Коллекции (Collections) — это папки, в которые вы можете сохранять свои запросы. Вы можете создать коллекцию «Мой Интернет-магазин» и разложить запросы по папкам: «Auth», «Products», «Orders». Это позволяет не вводить URL каждый раз заново.

    Переменные окружения (Environments) — это профессиональная фича. Представьте, что у вас есть локальный сервер (localhost:3000) и боевой сервер (api.production.com). Чтобы не менять URL в каждом запросе руками, вы создаете переменную {{baseUrl}}.

    В запросе вы пишете {{baseUrl}}/users. Теперь, переключая окружение в правом верхнем углу, вы мгновенно меняете адрес, куда летят запросы.

    Swagger: Интерактивная карта API

    Если Postman — это инструмент для проверки, то Swagger (сейчас чаще называемый OpenAPI) — это инструмент для понимания.

    API — это контракт. Разработчик сервера обещает: «Если ты пришлешь мне JSON такой структуры на этот адрес, я создам пользователя». Но где прочитать этот контракт? В переписке в мессенджере? В Word-документе, который обновляли полгода назад?

    Swagger решает проблему актуальной документации. Это стандарт описания REST API. Чаще всего он генерируется автоматически прямо из кода бэкенда. Если программист поменял код, документация обновилась сама.

    !Веб-интерфейс Swagger UI, отображающий список доступных методов API

    Как читать Swagger?

    Обычно Swagger представляет собой веб-страницу. Давайте разберем её структуру.

    #### 1. Список контроллеров Все методы сгруппированы по ресурсам. Вы увидите заголовки вроде User-Controller (управление пользователями) или Order-Controller (управление заказами).

    #### 2. Эндпоинты (Endpoints) Раскрыв контроллер, вы увидите список путей (URL). Они раскрашены разными цветами для удобства: * Синий: GET (получение) * Зеленый: POST (создание) * Оранжевый: PUT (обновление) * Красный: DELETE (удаление)

    #### 3. Параметры и Тело запроса Нажав на конкретный метод (например, POST /users), вы увидите подробную инструкцию: * Parameters: Какие параметры можно передать в URL (например, ID пользователя). * Request Body: Пример JSON, который сервер ожидает получить. Там же указано, какие поля обязательны (required), а какие нет.

    #### 4. Ответы (Responses) Ниже описано, что сервер может ответить. Это не только успешный код 200, но и возможные ошибки. Например, документация может предупредить: «Если вы не пришлете пароль, вернется 400 Bad Request».

    Schemas (Схемы данных)

    В самом низу страницы Swagger обычно находится раздел Schemas или Models. Там описаны все объекты данных, которые используются в API.

    Например, схема User покажет, что у пользователя есть: * id (integer) * username (string) * email (string, format: email) * role (enum: [admin, user])

    Это помогает фронтенд-разработчикам заранее подготовить интерфейс, зная типы данных.

    Кнопка «Try it out»

    Самая киллер-фича Swagger — кнопка Try it out (Попробовать). Она превращает документацию в упрощенный Postman.

  • Нажимаете Try it out.
  • Поля становятся редактируемыми.
  • Вы вводите параметры или JSON.
  • Нажимаете Execute (Выполнить).
  • Swagger отправляет реальный запрос на сервер и показывает вам ответ прямо на странице.
  • Это невероятно удобно для быстрой проверки: «А работает ли вообще этот метод?».

    Рабочий процесс: От Swagger к Postman

    Как эти два инструмента работают в связке? Рассмотрим типичный день разработчика.

    Задача: Вам нужно реализовать на сайте форму регистрации.

  • Изучение (Swagger): Вы открываете Swagger, находите метод POST /register. Смотрите, какие поля обязательны. Видите, что поле password должно быть минимум 8 символов.
  • Эксперимент (Postman): Вы не пишете сразу код сайта. Сначала вы идете в Postman. Создаете новый запрос, копируете URL из Swagger. Формируете JSON-тело. Пробуете отправить.
  • Отладка (Postman): Сервер вернул ошибку 400. Вы смотрите сообщение: «Email already exists». Ага, значит, нужно обрабатывать такую ошибку. Вы пробуете другой email. Успех! 201 Created.
  • Реализация (Код): Теперь, когда вы точно знаете, как работает API и какие ответы приходят, вы пишете код на JavaScript/Python/Java, который делает то же самое, что вы только что сделали руками.
  • Импорт и Экспорт

    Еще одна полезная связь: Swagger можно импортировать в Postman.

    Если у вас есть ссылка на спецификацию Swagger (обычно это файл swagger.json или openapi.yaml), вы можете нажать в Postman кнопку Import, вставить ссылку, и Postman автоматически создаст Коллекцию со всеми запросами, описанными в документации. Вам останется только подставить свои данные.

    Заключение

    Postman и Swagger — это не просто утилиты, это язык общения в команде.

    * Swagger говорит: «Вот так я должен работать». * Postman подтверждает: «Я проверил, это действительно так работает».

    Владение этими инструментами отличает новичка от профессионала. Вы перестаете гадать, почему не работает запрос, и начинаете видеть полную картину обмена данными.

    В следующей, заключительной части нашего теоретического блока, мы поговорим о безопасности. Вы узнаете, что такое токены, зачем нужен HTTPS и почему нельзя хранить пароли в открытом виде.