Вопрос или проблема
Можно ли использовать 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) и получить:
- Код статуса HTTP.
- Тело ответа.
Если вы хотите избавиться от лишней информации, такой как заголовки, методы и т.д., это вполне реально. Давайте рассмотрим, как можно добиться такого результата при помощи команды 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
Здесь вы получите:
- Тело ответа от сервера (например, в формате JSON).
- Код статуса ответа (в данном примере 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
позволяет отфильтровать ненужные данные, сосредоточив внимание на получении кода статуса и тела ответа.