Рубрика: api-integrations

  • REST API для начинающих разработчиков: запросы, ответы и обработка ошибок

    REST API для начинающих разработчиков: запросы, ответы и обработка ошибок

    REST API — это самый практичный способ заставить разные системы общаться друг с другом через HTTP. Если научиться правильно читать запросы, ответы и коды ошибок, становится проще и писать клиент, и отлаживать интеграции, и не путаться в поведении сервиса. Когда я начинал автоматизировать сбор объявлений с разных досок недвижимости, именно REST-интерфейсы стали тем клеем, который связал парсер, базу, аналитику и пользовательскую часть. Без чёткого понимания HTTP-семантики любой агрегатор превращается в хрупкую конструкцию, которая ломается на каждой мелочи.

    Что такое REST API простыми словами

    REST API — это набор правил, по которым приложение отправляет запросы к серверу и получает ответы. Обычно сервер работает с ресурсами: пользователи, объявления, заказы, квартиры, платежи, фильтры и так далее. В моих проектах по анализу рынка недвижимости ресурсами выступают карточки объектов, выдачи поиска, избранное, подписки на изменение цены, заявки на просмотр — всё это отдельные сущности, к которым клиент обращается по понятным адресам.

    Для разработчика REST API удобен тем, что почти всё строится вокруг стандартного HTTP:

    • метод запроса показывает, что нужно сделать;
    • адрес указывает, с каким ресурсом работаем;
    • тело запроса содержит данные;
    • статус ответа говорит, чем всё закончилось;
    • тело ответа возвращает результат или описание ошибки.

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

    Из чего состоит HTTP-запрос

    Типичный запрос к REST API включает несколько частей:

    • Метод — действие: получить, создать, изменить, удалить.
    • URL — путь к ресурсу.
    • Заголовки — служебная информация: тип контента, авторизация, язык, кэширование.
    • Параметры строки запроса — фильтры, сортировка, пагинация.
    • Тело запроса — данные, которые отправляются на сервер, чаще всего в JSON.

    На практике, когда вы шлёте поисковый запрос к сервису объявлений, метод и URL определяют общую операцию, а query-параметры и JSON-тело — конкретные фильтры: город, диапазон цен, число комнат, страница выдачи.

    Пример запроса

    POST /api/v1/properties/search HTTP/1.1
    Host: api.example.com
    Content-Type: application/json
    Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
    
    {
      "city": "moscow",
      "price_min": 8000000,
      "price_max": 18000000,
      "rooms": [1, 2],
      "page": 1,
      "per_page": 20,
      "sort": "price_asc"
    }

    Здесь POST обычно означает создание нового объекта, но в реальных интеграциях его часто используют и для сложных поисковых операций, когда нужно передать большой JSON с фильтрами. Через GET такие запросы неудобны: URL раздувается, а прокси и логи начинают резать длинные строки.

    Основные HTTP-методы и когда их использовать

    Для начинающих важнее всего понимать несколько базовых методов.

    Метод Что делает Когда использовать
    GET Получает данные Список объектов, карточка объекта, справочники
    POST Создаёт новый ресурс Создание заявки, объекта, пользователя
    PUT Полностью заменяет ресурс Полное обновление объекта
    PATCH Частично изменяет ресурс Меняется только часть полей
    DELETE Удаляет ресурс Удаление записи, если это разрешено

    В контексте недвижимости эти методы ложатся на типовые сценарии: GET тянет карточки и выдачи, POST сохраняет новое объявление или подписку на объект, PATCH обновляет статус «продано/снято с публикации», а DELETE убирает из публичного доступа, хотя саму запись физически можно не удалять.

    Важный нюанс

    • GET не должен менять данные на сервере. Если вы видите API, где через GET создаются сущности, перед вами плохо спроектированный сервис — и в интеграции с ним будут сюрпризы.
    • POST часто используют для создания, но иногда и для сложных операций, которые нельзя удобно выразить через GET.
    • PUT лучше применять, когда клиент отправляет весь объект целиком. Если вы обновляете только цену и статус квартиры, более уместен PATCH.
    • PATCH удобен, если нужно поменять только одно или несколько полей.
    • DELETE не всегда означает физическое удаление: иногда это мягкое удаление, когда запись только помечается как скрытая. Для архивов объявлений это критично — вы не хотите терять историю цен из-за того, что кто-то случайно вызвал метод удаления.

    Как устроен ответ REST API

    Ответ сервера обычно состоит из трёх частей:

    • HTTP-статус — успешен ли запрос;
    • заголовки — служебная информация;
    • тело ответа — данные или ошибка.

    Когда пишете клиента для агрегатора, важно смотреть не только в JSON, но и в заголовки: например, X-RateLimit-Remaining подскажет, сколько запросов осталось до блокировки, а Link может содержать ссылки на следующую страницу выдачи.

    Пример успешного ответа

    HTTP/1.1 200 OK
    Content-Type: application/json
    Date: Tue, 17 Jun 2025 10:15:00 GMT
    
    {
      "id": 42,
      "title": "2-комнатная квартира, 54 м²",
      "price": 12500000,
      "currency": "RUB",
      "address": "Москва, Ленинский проспект, 45",
      "status": "active"
    }

    Чаще всего 200 OK означает, что запрос выполнен успешно и сервер вернул данные.

    Коды ответов, которые нужно знать в первую очередь

    REST API живёт на кодах статуса. Для практики достаточно выучить несколько групп.

    Код Значение Что делать клиенту
    200 OK Всё прошло успешно Использовать данные ответа
    201 Created Создан новый ресурс Проверить Location, если он есть
    204 No Content Всё прошло успешно, но тела ответа нет Не ждать JSON
    400 Bad Request Ошибка в запросе Проверить формат и параметры
    401 Unauthorized Нужна авторизация Обновить или передать токен
    403 Forbidden Доступ запрещён Проверить права доступа
    404 Not Found Ресурс не найден Уточнить URL или идентификатор
    409 Conflict Конфликт состояния Повторить с другими данными
    422 Unprocessable Entity Данные валидны по формату, но не подходят по смыслу Исправить бизнес-ошибку
    429 Too Many Requests Слишком много запросов Уменьшить частоту или добавить retry
    500 Internal Server Error Ошибка на стороне сервера Повторить позже или логировать
    502/503/504 Проблема у промежуточного звена или сервиса Повторить запрос с паузой

    Если вы пишете парсер, который ходит по нескольким доскам объявлений, разница между 403 и 429 станет для вас критичной: первое — это про доступ, второе — про темп запросов. Не перепутайте, иначе будете бесконечно перезапрашивать то, что вам просто не отдадут без платного ключа.

    Как запомнить логику

    • 2xx — успех.
    • 4xx — проблема в запросе или правах.
    • 5xx — проблема на стороне сервера.

    Это базовое правило помогает быстро понимать, где искать причину сбоя: в клиенте, в данных или в серверной логике. Когда интеграция с CRM застройщика падает с 500, винить свой код бессмысленно — надо логировать и пробовать позже. А вот 400 почти всегда означает ошибку в формировании параметров: неправильный JSON, неверный тип поля, пропущенный обязательный фильтр.

    Как читать тело ответа

    Формат ответа обычно JSON. В нём могут быть:

    • сама сущность;
    • массив сущностей;
    • метаданные;
    • информация об ошибке.

    Когда вы агрегируете объявления из нескольких источников, вам важно заранее договориться с самим собой о форме ответа: если один сервис возвращает массив напрямую, а второй — объект с полем data, парсер должен уметь оба варианта. Иначе вы получите хаос на этапе сохранения в базу.

    Пример ответа со списком

    HTTP/1.1 200 OK
    Content-Type: application/json
    
    {
      "data": [
        {
          "id": 1,
          "title": "1-комнатная квартира",
          "price": 9500000,
          "address": "Москва, ул. Тверская, 12"
        },
        {
          "id": 2,
          "title": "Студия, 28 м²",
          "price": 6800000,
          "address": "Москва, ул. Арбат, 5"
        }
      ],
      "meta": {
        "total": 142,
        "page": 1,
        "per_page": 20,
        "next_page": 2
      }
    }

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

    Ошибки API: как их правильно обрабатывать

    Главная ошибка новичков — смотреть только на текст ошибки. Правильный подход: сначала читать HTTP-код, потом тело ответа, потом уже решать, что делать. Тело может быть неинформативным или вообще отсутствовать, а код статуса — это всегда первый сигнал о типе проблемы.

    Базовая стратегия обработки ошибок

    • 400 — показать пользователю, что данные введены неверно.
    • 401 — попросить заново авторизоваться.
    • 403 — объяснить, что действие недоступно.
    • 404 — сообщить, что ресурс не найден.
    • 409 — предложить изменить данные или повторить действие.
    • 422 — подсветить конкретные поля формы.
    • 429 — сделать паузу и повторить позже.
    • 5xx — не винить пользователя, а логировать сбой и пробовать повтор.

    В сервисах по недвижимости 422 встречается часто: например, вы пытаетесь создать подписку на объект, который уже снят с продажи. Формат запроса верный, но бизнес-состояние не позволяет выполнить операцию.

    Пример ошибки в JSON

    HTTP/1.1 422 Unprocessable Entity
    Content-Type: application/json
    
    {
      "error": {
        "code": "validation_failed",
        "message": "Проверьте правильность заполнения полей",
        "fields": {
          "price_max": "Максимальная цена не может быть меньше минимальной",
          "email": "Некорректный адрес электронной почты"
        }
      }
    }

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

    Практический алгоритм: как работать с REST API

    Ниже — простой порядок, который помогает не теряться в интеграциях.

    1. Определи ресурс

    Сначала пойми, с чем работает API:

    • объявления;
    • пользователи;
    • платежи;
    • заявки;
    • фильтры.

    Когда подключаешь новый источник данных о недвижимости, первым делом смотрю на структуру ресурсов: как называются объекты, как они связаны, есть ли вложенные сущности вроде фото или планировок. От этого зависит, сколько запросов понадобится для полной выгрузки.

    2. Посмотри метод

    Уточни, что делает запрос:

    • получить;
    • создать;
    • обновить;
    • удалить.

    Не полагайтесь на догадки: иногда сервис использует POST для получения отчёта, потому что параметры слишком объёмные для GET. Читайте документацию, а ещё лучше — тестируйте в песочнице.

    3. Проверь параметры

    Раздели их на три группы:

    • путь: /api/v1/properties/42;
    • query-параметры: ?city=moscow&page=2;
    • тело запроса: JSON с данными.

    В парсинге часто приходится генерировать URL динамически: город, район, тип сделки, диапазон цены. Если перепутать query и body, сервер либо проигнорирует фильтр, либо вернёт 400. Отлаживать такое в большом парсере — то ещё удовольствие.

    4. Обработай статус

    Не считай 200 единственным успехом:

    • 201 тоже успех;
    • 204 тоже успех;
    • 202 может означать, что задача принята в работу, но ещё не завершена.

    Например, когда вы запускаете выгрузку большого объёма объявлений, сервер может вернуть 202 Accepted с идентификатором задачи. Это нормально: результат появится позже, не нужно сразу повторять запрос.

    5. Разбери ошибку

    Если пришёл 4xx или 5xx, не показывай пользователю сырой ответ сервера. Лучше:

    • сохранить детали в лог;
    • вывести понятное сообщение;
    • предложить следующий шаг.

    Сырой JSON с полями вида stack_trace или внутренними идентификаторами пугает пользователя и раскрывает лишнее. В клиенте для мониторинга цен я логирую всё, а наружу вывожу только человекочитаемое описание и действие.

    Типовые ошибки новичков

    1. Отправка данных не тем методом

    Например, вместо POST используют GET и пытаются передать сложный JSON в URL. Это плохо работает и быстро ломается. Лично видел, как парсер с длиннющим query-параметром падал на уровне nginx еще до попадания в приложение — URL просто обрезался.

    2. Игнорирование кодов 204, 201, 202

    Некоторые разработчики ждут только 200 OK, хотя успешный ответ может быть и другим. Если сервер вернул 204 No Content после обновления статуса объявления, а клиент пытается распарсить пустое тело как JSON — получите ошибку там, где всё прошло успешно.

    3. Отсутствие обработки 401 и 403

    Если токен истёк, приложение должно это понять и мягко переавторизовать пользователя. В автоматизированных системах, которые работают без человека, нужно заранее закладывать обновление токена по расписанию и хранить refresh-токен в безопасном месте.

    4. Один общий текст ошибки для всех случаев

    Пользователю бесполезно сообщение вроде «Что-то пошло не так». Лучше различать:

    • неверные данные;
    • отсутствие доступа;
    • временную проблему сервера.

    Когда человек пользуется калькулятором ипотеки и видит «Ошибка», он не понимает, что именно чинить: свою ставку, интернет или ждать. А если вы скажете «Сервер временно недоступен, попробуйте через пару минут» — это уже нормальный UX.

    5. Повтор запросов без ограничений

    Если сервер уже вернул 429, бесконечные повторы только ухудшат ситуацию. Нужны паузы, экспоненциальный backoff и лимиты. В парсинге досок объявлений это правило — вопрос выживания: заблокируют IP или ключ API, и вся выгрузка встанет.

    Что важно предусмотреть в клиенте

    Хороший клиент для REST API умеет не только отправлять запросы, но и работать с реальностью.

    Мини-чек-лист

    • Проверять статус ответа.
    • Валидировать входные данные до отправки.
    • Логировать ошибки сети и сервера.
    • Обрабатывать таймауты.
    • Поддерживать повтор запросов там, где это безопасно.
    • Учитывать пагинацию и лимиты.
    • Уметь обновлять токен авторизации.
    • Понимать разницу между пустым ответом и ошибкой.

    Если вы собираете данные для аналитики цен, пагинация и лимиты — не опция, а необходимость: без аккуратного обхода страниц вы не получите полную выборку, а без учёта rate limit быстро упрётесь в блокировку.

    Пример логики обработки ответа

    async function handleResponse(response) {
      if (response.status >= 200 && response.status = 500) {
        // серверная ошибка — логируем и пробуем позже
        logServerError(response);
        if (isRetryable(response.request)) {
          await delay(exponentialBackoff());
          return retryRequest(response.request);
        }
        throw new AppError('Сервис временно недоступен');
      }
    
      // 400, 403, 404, 409, 422 и другие клиентские ошибки
      const errorData = await response.json().catch(() => null);
      throw new ClientError(errorData, response.status);
    }

    Такой подход помогает не смешивать сетевые проблемы, ошибки формы и серверные сбои. Когда интеграция с риелторской CRM начинает возвращать 502 из-за проблем у них на стороне, ваш клиент не должен падать с нечитаемым стеком — он должен аккуратно уйти в ретрай или сообщить о временной недоступности.

    Когда REST API особенно полезен

    REST API хорошо подходит, если нужно:

    • связать веб-приложение и сервер;
    • собрать данные из нескольких источников;
    • построить личный кабинет;
    • автоматизировать импорт и экспорт;
    • интегрировать сервисы между собой;
    • передавать данные в CRM, аналитику или внутренние инструменты.

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

    Вывод

    REST API — это не сложная магия, а понятный набор правил: метод запроса показывает действие, URL указывает ресурс, статус ответа сообщает результат, а тело содержит данные или ошибку. Если с самого начала правильно читать коды, разделять клиентские и серверные ошибки и аккуратно обрабатывать ответы, интеграции становятся намного стабильнее и предсказуемее. Для меня как для разработчика, который начинал с инди-игр, а потом переключился на автоматизацию рынка недвижимости, REST стал тем базовым слоем, на котором держатся и парсеры объявлений, и калькуляторы, и агрегаторы аналитики.

    FAQ

    Что такое REST API простыми словами?

    Это способ обмена данными между приложениями через HTTP, где каждый запрос обращается к конкретному ресурсу. Всё строится на стандартных методах и статусах, поэтому логика предсказуема.

    Чем GET отличается от POST?

    GET получает данные, а POST обычно создаёт новый ресурс или запускает действие на сервере. GET не должен менять состояние, а POST может выполнять операции с побочными эффектами.

    Почему ошибка может быть не только 400?

    Потому что есть разные типы проблем: с запросом, с правами доступа, с состоянием ресурса, с сервером или с лимитами. Код статуса как раз указывает на источник проблемы.

    Всегда ли ответ приходит в JSON?

    Нет. Чаще всего да, но API может возвращать и пустой ответ, и другой формат, и даже файл. Поэтому важно проверять заголовок Content-Type и не пытаться парсить JSON из пустого тела.

    Что делать, если сервер вернул 500?

    Не пытаться «исправить» запрос на клиенте, а залогировать проблему и повторить позже, если операция допускает повтор. Ошибка на стороне сервера не связана с вашими данными — лучше сделать паузу с экспоненциальным бекoff и сообщить пользователю о временной недоступности.