Возврат кода состояния и тела в curl

Вопрос или проблема

Можно ли использовать curl для вызова REST-сервиса (метод POST) и получения:

  • Кода состояния HTTP.
  • Тела ответа.

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

Например, я делаю:

$ curl -i -H 'Content-Type: application/json' -d @payload.json localhost:8080/apply
HTTP/1.1 100 

HTTP/1.1 400 
Content-Type: text/plain;charset=UTF-8
Content-Length: 42
Date: Fri, 22 Oct 2021 16:29:18 GMT
Connection: close

Недопустимый продукт: продукт не существует

Я знаю, что сервис возвращает код 400, который я вижу, а также сообщение об ошибке ответа Недопустимый продукт: продукт не существует, которое я также вижу, так что это хорошо.

Тем не менее, возможно ли избавиться от остальной части вывода?

Вместо -i для отображения заголовков ответа, вы можете использовать -w/--write-out с форматной строкой, содержащей переменную http_code:

curl --write-out '%{http_code}\n' ...

это выведет статус ответа (и перевод строки) после тела. Посмотрите man curl для других переменных, которые могут быть вам полезны.

Основываясь на решении @DonHolgo, можно добавить больше информации при выводе следующим образом:

curl --location 'https://foo.acme.com' \
--request POST \
--write-out '\nhttp_code=%{http_code}\nexitcode=%{exitcode}\n' --silent --show-error \
--header 'Content-Type: application/json' \
--data '{"foo": "bar","baz":"bim"}'

Вывод в этом случае комбинируется с ответом на POST:

{"requestId":"550aa1ff-0001-bf46-79ae-018cfe00dff7"}
http_code=202
exitcode=0

Вы можете захватить это в одну переменную и обработать 3 вещи: ответ POST (JSON), код ответа HTTP и код завершения команды cURL.

Вот мой хак, предполагая, что тело – это json:

curl -w '{"statusCode": %{http_code}}' | jq -sre add

Таким образом, на практике это выглядит так для jq:

echo '{"statusCode": 200} {"name": "Christian"}' | jq -sre add
{
  "statusCode": 200,
  "name": "Christian"
}

Затем вы можете делать такие вещи:

% echo '{"statusCode": 500} {"name": "Christian"}' | 
   jq -sre 'add | (.statusCode | in([200,201,202,204]))'
false
% echo $?
1

Таким образом, это дает вам возможность обрабатывать ошибки или не обрабатывать их для конкретных кодов http. Curl является довольно грубым инструментом в этом отношении. Параметр -f выдает код ошибки для любого кода, отличного от 200.

Ответ или решение

Вопрос: возможно ли с помощью cURL вызвать REST-сервис (метод POST) и получить:

  1. Код статуса HTTP.
  2. Тело ответа.

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

Использование параметров cURL

Для того чтобы получить информацию о коде статуса и теле ответа, используя cURL, вы можете воспользоваться параметром --write-out вместе с --silent и --show-error. Это позволит вам избежать лишней информации и получить только нужные данные.

Пример команды:

curl --request POST \
  --url http://localhost:8080/apply \
  --header 'Content-Type: application/json' \
  --data @payload.json \
  --silent --show-error \
  --write-out '\nhttp_code=%{http_code}\n'

Разбор команды

  • --request POST: указывает метод запроса.
  • --url http://localhost:8080/apply: указывает URL-адрес вашего REST-сервиса.
  • --header 'Content-Type: application/json': задает тип контента запроса.
  • --data @payload.json: передает данные из файла payload.json в теле запроса.
  • --silent: подавляет прогресс и ошибки, что делает вывод более лаконичным.
  • --show-error: выводит ошибки, если они имеются.
  • --write-out '\nhttp_code=%{http_code}\n': выводит код статуса HTTP после получения ответа.

Результат выполнения

Когда вы выполните данную команду, вывод будет выглядеть следующим образом:

{"response":"some response data"}
http_code=400

Здесь вы получите:

  1. Тело ответа от сервера (например, в формате JSON).
  2. Код статуса ответа (в данном примере 400).

Дополнительные возможности

Если вы хотите дополнительно обработать полученные данные, вы можете использовать такие инструменты, как jq. Например, вы можете объединить код статуса и тело ответа в один JSON-объект:

response=$(curl --request POST \
   --url http://localhost:8080/apply \
   --header 'Content-Type: application/json' \
   --data @payload.json \
   --silent --show-error)

http_code=$?

echo $response | jq --arg http_code "$http_code" '{statusCode: $http_code, body: .}'

Заключение

Таким образом, cURL предоставляет мощные возможности для работы с REST-сервисами, позволяя вам легко и быстро получать интересующую информацию. Использование параметров --write-out, --silent и --show-error позволяет отфильтровать ненужные данные, сосредоточив внимание на получении кода статуса и тела ответа.

Оцените материал
Добавить комментарий

Капча загружается...