Colourized, Pretty Printed JSON with cURL and Bash

Overview

Working with APIs I do a lot of manual testing on the command line using cURL. Typing out

1
curl -H "Accept: application/json" -H "Content-Type: application/json" -H "X-User-Email: name@example.com" -H "X-User-Token: a4pQnAiprk6-qczS3rn6"

over and over quickly becomes tiresome. Here I will explain a simple bash function I use that will simplify the command plus pretty print, and colourise the JSON output in your Terminal. This tutorial is written for intermediate developers using Macs, however, I’m sure all these commands will work fine on Linux machines. Let me know in the comments if you have a problem.

npm jsontool

First install jsontool from npm

https://www.npmjs.org/package/jsontool

1
npm install jsontool

Now you should be able to pipe cURL output to it, like so;

1
$ curl http://localhost:3000/api/v1/exercises | json

cURL output

Colourisation

You may have Python installed already, otherwise, run the following command..

1
brew install python

Followed by..

1
pip install pygments

Alternatively, you can install Pygments using Python’s built in easy_install

1
sudo easy_install pygments

You may need to reload your shell, so that $PATH is reloaded, I normally just create a new Terminal tab to do this.

Now we can pipe our JSON through the pygmentize tool that comes with pygments. It’s normally installed to /usr/local/bin:

1
2
$ which pygmentize
/usr/local/bin/pygmentize

Don’t forget to specify json as the lexer for pygmentize with -l json

1
$ curl http://localhost:3000/api/v1/exercises | json | pygmentize -l json

cURL output

A Bash Function

Now we can wrap this up in a simple bash function (add this to your ~/.bash_profile)

.bash_profile
1
2
3
4
function jcurl() {
    curl "$1" | json | pygmentize -l json
}
export -f jcurl

Reload your .bash_profile using..

1
source ~/.bash_profile

Now we can get the same result as before, just using the command like so..

1
$ jcurl http://localhost:3000/api/v1/exercises

Let’s modify the jcurl function a bit. If we replace the $1 shell variable, which takes the first argument from the command line as input, and replace it with $@, then it will act like

.bash_profile
1
2
3
4
function jcurl() {
    curl "$@" | json | pygmentize -l json
}
export -f jcurl

This allows us to pass more than one option to jcurl ..For example, if we wanted to pass headers..

1
jcurl -H "X-User-Token: a4pQnAiprk6-qczS3rn6" -H "X-User-Email: name@example.com" http://localhost:3000/api/v1/exercises

For added convenience, I decided to do this;

.bash_profile
1
2
3
4
function auth-jcurl() {
    curl -H "Accept: application/json" -H "Content-Type: application/json" -H "X-User-Email: $1" -H "X-User-Token: $2" ${@:3} | json | pygmentize -l json
}
export -f auth-jcurl

${@:3} is the array of command line arguments minus the first 2, (because we’ve already used them with $1 and $2).

We can now pass the username and access token to cURL and any additional options (which will be picked up by “$@”)

1
$ auth-jcurl name@example.com a4pQnAiprk6-qczS3rn6 http://localhost:3000/api/v1/exercises

Let me know in the comments below if you found this helpful, or can suggest any improvements.

Comments