The Problem
I tend toward using cURL when testing HTTP services, but I had a difficult time parsing the result when these services spit back unformatted JSON responses. To make my life a little easier, I set out to find a way to bend cURL to my will.
The Solution
Let's get straight to it. To make cURL display both response headers and formatted JSON, we need to make cURL send the headers to STDERR, so we can then send STDOUT to a formatting utility.
We can accomplish this as so.
curl -s -D "/dev/stderr" -X POST 'http://example.org/some/url' --data-binary @some-file | python -m json.tool
This will show a nicely formatted response like this.
HTTP/1.1 500 Internal Server Error
Content-Type: application/json; charset=utf-8
X-Powered-By: ASP.NET
Date: Wed, 18 Sep 2019 22:39:24 GMT
Content-Length: 114
{
"Status": 3,
"Timestamp": "2019-09-18T22:39:24.1659165Z",
"Error": {
"Code": 1,
"Message": "An error has occurred."
}
}
What's Going On Here?
Let's break this down a bit.
After some initial research into how to send the HTTP headers to STDERR, I found this article that demonstrated the use of -D "/dev/stderr"
.
Breaking the command down:
-s
will silence the statistics output of cURL-D "/dev/stderr"
will send the HTTP headers to STDERRpython -m json.tool
receives STDOUT, which is the JSON response of my service- The other options are specific to my service request, and are not relevant to the formatting
Note: you can also pipe the cURL output to a utility like jq, I just happen to use python -m json.tool.
A Step Further
These commands and then be turned into Bash aliases and functions.
I have this in my ~/.bashrc
.
alias curl-json='curl -s -D "/dev/stderr"'
curl-json-format()
{
curl-json "$@" | python -m json.tool
}
Now I can use this command!
curl-json-format -X POST 'http://example.org/some/url' --data-binary @some-file | python -m json.tool