HTTPie: удобная альтернатива curl для тестирования API

9 минут чтения
Средний рейтинг статьи — 4.8

curl давно стал стандартным инструментом для проверки HTTP-запросов из терминала. Он установлен почти везде, подходит для скриптов и умеет гораздо больше, чем просто ходить по URL. Но когда нужно быстро проверить REST API, отправить JSON, посмотреть заголовки и не держать в голове десяток флагов, curl часто выглядит тяжеловато.

HTTPie — консольный HTTP-клиент с более дружелюбным синтаксисом. Он заточен под работу с API: красиво форматирует ответы, подсвечивает JSON, проще отправляет параметры, заголовки и тело запроса. Для разработчика это часто означает меньше шума в команде и результат, который проще и быстрее прочитать.

Разберём, что умеет HTTPie, как его установить, чем он отличается от curl, где удобен в ежедневной разработке и когда всё равно стоит остаться на классическом curl.

Что такое HTTPie

HTTPie — это CLI-инструмент для выполнения HTTP-запросов. Основная команда называется http, а синтаксис специально сделан так, чтобы запросы читались почти как обычная фраза:

http GET https://api.example.com/users

Во многих случаях метод можно не указывать. Если вы просто обращаетесь к URL, HTTPie выполнит GET:

http https://api.example.com/users

Если в команде есть поля тела запроса, по умолчанию будет использован POST:

http https://api.example.com/users name="Anna" role="admin"

Главная идея HTTPie — сделать ручное тестирование HTTP API удобным. Он особенно полезен, когда вы:

  • проверяете новый эндпоинт во время разработки;
  • отлаживаете авторизацию и заголовки;
  • отправляете JSON и смотрите форматированный ответ;
  • проверяете веб-хуки и воспроизводите ошибки из логов;
  • хотите сохранить читаемую команду в README или issue.

Если нужно освежить базу по curl, у Statuser уже есть отдельный материал: Что такое curl и как им пользоваться. HTTPie не отменяет curl, а закрывает другой сценарий: интерактивную работу с HTTP API, где важны читаемость и скорость.

Установка HTTPie на Linux, macOS и Windows

HTTPie написан на Python, поэтому один из самых универсальных способов установки — через pipx. Он ставит CLI-приложения в изолированное окружение и не смешивает их с зависимостями проекта.

pipx install httpie

Проверить установку можно так:

http --version

На macOS удобно использовать Homebrew:

brew install httpie

На Ubuntu и Debian пакет часто доступен из репозиториев:

sudo apt update
sudo apt install httpie

Но в системных репозиториях версия может быть не самой свежей. Если нужны новые возможности, лучше использовать pipx.

На Windows можно установить через winget:

winget install HTTPie.HTTPie

Или через Chocolatey:

choco install httpie

После установки команда обычно называется http. Иногда дополнительно доступна команда https, которая автоматически использует схему https://, если URL передан без неё.

Пример:

https api.github.com

Это эквивалентно обращению к https://api.github.com.

Базовый синтаксис запросов

В HTTPie команда обычно строится так:

http [метод] URL [параметры] [заголовки] [поля]

Самый простой GET:

http GET https://httpbin.org/get

Или короче:

http https://httpbin.org/get

Запрос с query-параметрами делается через ==:

http https://httpbin.org/get search==httpie page==2 limit==10

В итоговый URL попадёт:

https://httpbin.org/get?search=httpie&page=2&limit=10

Заголовки задаются через Имя:значение:

http https://api.example.com/users \
  Authorization:"Bearer $TOKEN" \
  X-Request-ID:test-123

Тело JSON-запроса задаётся через поле=значение:

http POST https://api.example.com/users \
  name="Ivan" \
  email="ivan@example.com"

По умолчанию HTTPie отправит JSON и добавит подходящий Content-Type. Это одно из главных отличий от curl: не нужно каждый раз писать -H "Content-Type: application/json" и вручную экранировать JSON-строку.

Для вложенных значений и чисел используется оператор :=. Он говорит HTTPie: воспринимай значение как JSON, а не как строку.

http POST https://api.example.com/users \
  name="Ivan" \
  age:=34 \
  active:=true \
  roles:='["admin", "editor"]' \
  profile:='{"timezone":"Europe/Moscow"}'

Если написать age=34, значение уйдёт как строка "34". Если написать age:=34, оно уйдёт как число 34.

Это удобно при тестировании API, где сервер строго различает типы данных. Например, FastAPI, NestJS и другие фреймворки часто валидируют входные схемы. Если вы экспериментируете с такими сервисами, могут пригодиться материалы Как работает FastAPI и как поднять простое REST API на Python и Как создать REST API на NestJS: пошаговый гайд.

Отправка JSON, форм и файлов

JSON — сценарий по умолчанию в HTTPie, поэтому POST-запрос выглядит лаконично:

http POST http://localhost:8000/api/tasks \
  title="Check backups" \
  priority:="2" \
  done:=false

Если тело запроса уже лежит в файле, его можно передать через stdin:

http POST http://localhost:8000/api/tasks < task.json

Это полезно для больших payload, которые неудобно писать прямо в командной строке. Например, для воспроизведения ошибки из продакшена: вы сохраняете тело запроса в payload.json, убираете чувствительные данные и отправляете его на локальный стенд.

Для отправки HTML-формы используется флаг --form или короткий вариант -f:

http --form POST https://example.com/login \
  username="demo" \
  password="secret"

В этом случае данные уйдут как application/x-www-form-urlencoded.

Загрузка файла через multipart/form-data выглядит так:

http --form POST https://api.example.com/upload \
  description="avatar" \
  file@./avatar.png

HTTPie сам сформирует multipart-запрос и выставит нужные заголовки.

Если нужно отправить полностью сырой body, можно использовать перенаправление:

http POST https://api.example.com/import \
  Content-Type:application/json \
  < dump.json

Для XML, plain text или нестандартных форматов достаточно явно указать Content-Type:

http POST https://api.example.com/events \
  Content-Type:text/plain \
  < event.txt

Такой подход удобен при проверке веб-хуков: можно сохранить пример входящего события в файл и многократно отправлять его на локальный или тестовый эндпоинт. Если вам актуальна тема веб-хуков, советуем материал Что такое веб-хуки и как их использовать в автоматизации.

Заголовки, авторизация и cookies

Большинство реальных API требуют авторизации. В HTTPie есть несколько способов передать credentials.

1) Bearer-токен через заголовок — самый универсальный вариант:

http https://api.example.com/me \
  Authorization:"Bearer $TOKEN"

Такую команду легко вставить в документацию, issue или CI-лог. Токен лучше брать из переменной окружения, а не писать прямо в истории shell.

2) Basic Auth через -a — удобно для простых сервисов, staging-окружений и внутренних инструментов:

http -a username:password https://api.example.com/admin

Если пароль не указан, HTTPie может запросить его интерактивно:

http -a username https://api.example.com/admin

3) Cookies — можно передать вручную через заголовок:

http https://example.com/profile \
  Cookie:"session=abc123"

Но для повторяющихся запросов удобнее использовать сессии. О них ниже.

4) Кастомные заголовки — задаются тем же синтаксисом:

http https://api.example.com/orders \
  X-Tenant-ID:company-42 \
  X-Debug:true \
  Accept:application/json

Обратите внимание на кавычки. Если в значении есть пробелы, спецсимволы или переменные, лучше заключать его в кавычки:

http https://api.example.com/search \
  X-Client-Name:"internal test client"

Для JWT-сценариев HTTPie особенно приятен: вы можете получить токен одним запросом, сохранить его в переменную и использовать дальше.

TOKEN=$(http --body POST http://localhost:3000/auth/login \
  email="admin@example.com" \
  password="secret" \
  | jq -r '.accessToken')
 
http http://localhost:3000/profile \
  Authorization:"Bearer $TOKEN"

Здесь --body выводит только тело ответа, а jq достаёт поле accessToken. Если вы реализуете JWT на Node.js, полезно свериться с материалом Как реализовать аутентификацию по JWT в Node.js + Express.

Вывод, отладка и работа с ответами

Одна из сильных сторон HTTPie — читаемый вывод. По умолчанию он форматирует JSON и подсвечивает синтаксис, если терминал поддерживает цвета. Это заметно удобнее, чем получать длинную минифицированную строку.

Посмотреть только заголовки ответа — http --headers https://api.example.com/users (короткий вариант -h).

Посмотреть только тело — http --body https://api.example.com/users (короткий вариант -b).

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

http --verbose POST https://api.example.com/users name="Anna"

Короткий вариант — флаг -v.

В подробном режиме видно:

  • какой метод отправлен;
  • какой URL получился после добавления query-параметров;
  • какие заголовки ушли;
  • какое тело запроса отправлено;
  • какой статус и заголовки вернул сервер;
  • какое тело пришло в ответ.

Это помогает быстро находить ошибки вроде неправильного Content-Type, отсутствующего токена, неверного пути или неожиданного редиректа.

Для управления выводом есть флаг --print. Он принимает комбинацию символов:

  • H — заголовки запроса;
  • B — тело запроса;
  • h — заголовки ответа;
  • b — тело ответа.

Например, вывести заголовки запроса и ответа, но без body:

http --print=Hh POST https://api.example.com/users name="Anna"

Или вывести всё:

http --print=HhBb POST https://api.example.com/users name="Anna"

Для проверки редиректов используется --follow:

http --follow https://example.com/old-page

Если нужно только увидеть, куда ведёт редирект, часто достаточно заголовков:

http --headers https://example.com/old-page

Для HTTPS-отладки можно временно отключить проверку сертификата:

http --verify=no https://localhost:8443

В продакшене так делать не стоит, но для локального стенда с самоподписанным сертификатом это нормально. Для более глубокой проверки TLS из терминала лучше использовать специализированные инструменты, например openssl s_client; об этом есть отдельный гайд openssl s_client.

Сессии, повторяемые запросы и скрипты

HTTPie умеет хранить сессии: cookies, некоторые заголовки и параметры авторизации. Это удобно, когда API сначала требует логин, а затем несколько запросов в рамках одной авторизованной сессии.

Пример логина:

http --session=dev POST https://example.com/login \
  username="demo" \
  password="secret"

Следующий запрос с той же сессией:

http --session=dev https://example.com/profile

Если сервер установил cookie при логине, HTTPie подставит её автоматически.

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

Для автоматизации полезен флаг --check-status. Он заставляет HTTPie возвращать ненулевой код выхода при HTTP-ошибках:

http --check-status https://api.example.com/health

Это можно использовать в простых shell-скриптах:

#!/usr/bin/env bash
set -e
 
http --check-status --timeout=5 https://api.example.com/health > /dev/null
echo "API is healthy"

Но это не замена полноценному мониторингу: такая команда проверяет эндпоинт только с одной машины. Для регулярного контроля доступности лучше подходит внешний сервис вроде Statuser, который проверяет сайт по расписанию и уведомляет о сбоях, а HTTPie остаётся инструментом диагностики и воспроизведения проблемы.

Если вы строите проверки API системно, полезно различать ручной тест, синтетическую проверку и метрики приложения. Об этом подробнее: Синтетический мониторинг API и Мониторинг HTTP API. RED-метрики, latency и error budget на практике.

HTTPie против curl: что выбрать

HTTPie часто называют альтернативой curl, но правильнее считать его дополнением. У инструментов разные сильные стороны.

1) Читаемость команд — у HTTPie она обычно выше. Сравните отправку JSON.

curl:

curl -X POST https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $TOKEN" \
  -d '{"name":"Anna","age":30,"active":true}'

HTTPie:

http POST https://api.example.com/users \
  Authorization:"Bearer $TOKEN" \
  name="Anna" \
  age:=30 \
  active:=true

Вторая команда короче и меньше подвержена ошибкам с кавычками.

2) Доступность в окружениях — curl почти всегда уже установлен. На серверах, в контейнерах, minimal images и CI-окружениях его обычно не нужно добавлять. HTTPie чаще придётся устанавливать отдельно.

3) Поддержка протоколов — curl универсальнее. Он работает не только с HTTP, но и с FTP, SMTP, IMAP, SCP, SFTP и другими протоколами. HTTPie сфокусирован на HTTP API.

4) Скрипты и совместимость — curl остаётся надёжным выбором для переносимых shell-скриптов. У него стабильный интерфейс, огромная база примеров и меньше внешних зависимостей. Если команда будет выполняться на сотнях серверов, curl практичнее.

5) Интерактивная разработка — здесь выигрывает HTTPie. Быстро отправить JSON, увидеть красивый ответ, добавить заголовок, проверить query-параметры — всё это делается проще.

6) Документация API — примеры на HTTPie часто легче читать. Они хорошо подходят для внутренних README, инструкций для QA и onboarding-разделов. Но если API публичный, обычно стоит давать примеры и для curl, потому что он установлен у большего числа пользователей.

Практичный подход такой: HTTPie — для разработки, отладки и демонстрации запросов; curl — для универсальных инструкций, минимальных окружений и скриптов, где важна максимальная переносимость.

Практические сценарии использования

HTTPie особенно полезен в ежедневных задачах, где нужно быстро проверить гипотезу.

1) Проверить health endpoint — быстрый способ понять, отвечает ли сервис:

http --headers https://api.example.com/health

Если сервер возвращает 200 OK, можно смотреть тело. Если 500, 502 или 503 — сразу видно статус и заголовки. Такой ручной запрос полезен для диагностики, но не заменяет внешний регулярный мониторинг наподобие Statuser.

2) Проверить CORS-заголовки — можно сымитировать запрос с Origin:

http --headers OPTIONS https://api.example.com/users \
  Origin:https://frontend.example.com \
  Access-Control-Request-Method:GET

Так видно, возвращает ли сервер Access-Control-Allow-Origin, Access-Control-Allow-Methods и другие нужные заголовки.

3) Воспроизвести ошибку из логов — если в логах есть метод, URL, заголовки и тело, их легко собрать в одну команду:

http POST https://api.example.com/orders \
  Authorization:"Bearer $TOKEN" \
  X-Request-ID:from-logs-123 \
  userId:=42 \
  amount:=1990 \
  currency="RUB"

4) Проверить идемпотентность — для API, где важна защита от дублей, можно отправлять один и тот же Idempotency-Key:

http POST https://api.example.com/payments \
  Authorization:"Bearer $TOKEN" \
  Idempotency-Key:test-payment-001 \
  amount:=1000 \
  currency="RUB"

Если второй запрос создаёт повторную операцию, проблема не в клиенте, а в логике API. Подробнее про этот класс ошибок: Что такое idempotency в API и как избежать дубликатов запросов.

5) Скачать файл — у HTTPie есть режим загрузки:

http --download https://example.com/archive.zip

Можно указать имя файла:

http --download https://example.com/archive.zip -o archive.zip

6) Проверить статус-код в CI — минимальная проверка после деплоя:

http --check-status --timeout=10 https://api.example.com/health > /dev/null

Это не полноценный smoke test, но хорошая быстрая защита от ситуации «деплой прошёл, а сервис не отвечает».

Типичные ошибки при работе с HTTPie

HTTPie простой, но несколько нюансов часто сбивают с толку.

1) Путают = и := — name=Ivan отправит строку, а age:=30 отправит число. Для boolean, чисел, массивов и объектов используйте :=.

http POST :8000/items \
  title="Book" \
  price:=500 \
  available:=true

2) Забывают кавычки в заголовках — shell может неправильно обработать пробелы и спецсимволы. Безопаснее писать так:

http :8000/private Authorization:"Bearer $TOKEN"

3) Ожидают JSON, но отправляют form-data — без --form HTTPie по умолчанию отправляет JSON. Если сервер ждёт обычную форму, добавьте --form.

http --form POST :8000/login username=demo password=secret

4) Используют --verify=no как постоянное решение — отключение проверки TLS подходит для локальной разработки, но не для реального API. Если сертификат не проходит проверку, лучше исправить цепочку сертификатов или явно указать доверенный CA.

5) Хранят токены в истории команд — если вставить реальный токен прямо в команду, он может остаться в shell history. Лучше использовать переменные окружения:

export TOKEN="..."
http :8000/me Authorization:"Bearer $TOKEN"

6) Путают ручную проверку и мониторинг — HTTPie отлично отвечает на вопрос «что вернёт этот эндпоинт сейчас из моей среды». Но он не отвечает на вопрос «падал ли API ночью для пользователей из другой сети». Для этого нужны регулярные проверки, логи, метрики и алерты.

FAQ

HTTPie полностью заменяет curl?
Нет. HTTPie удобнее для ручного тестирования HTTP API, но curl универсальнее, чаще предустановлен и лучше подходит для переносимых скриптов.

Как отправить JSON через HTTPie?
Просто передайте поля после URL: http POST :8000/users name=Anna age:=30. Строки задаются через =, JSON-значения — через :=.

Можно ли использовать HTTPie в CI/CD?
Да, особенно с --check-status и --timeout. Но если окружение минимальное и нельзя ставить дополнительные пакеты, проще использовать curl.

Почему команда называется http, а не httpie?
HTTPie — название проекта, а основной исполняемый файл CLI — http. В некоторых установках также доступна команда https.

Опубликовано 31 октября 20269 минут чтенияГригорий Чалый
Средний рейтинг статьи — 4.8

Настроить мониторинг за 30 секунд

Надёжные уведомления о даунтаймах. Без ложных срабатываний