March 31, 2019

Quickly testing and verifying APIs using curl and friends

Quickly testing and verifying APIs using curl and friends

Often you need to need to quickly test or verify an API from the command line. Perhaps you've SSHd into a remote server, or just dont want to leave the prompt, so you don't/can't use graphical tools like:

Its hard to write a better comparison of tools than this article, so we wont do that here. We will just show some basic usage of these tools, to get you going. We will show some simple calls, viewing headers, and formatting of the json response.

curl

Here is how to do a simple call to an API with curl. If you dont add the pipe to jq, the json response wont be formatted.

curl https://api.chucknorris.io/jokes/random\?category\=\{sport\} | jq '.'
  
{
  "category": [
    "sport"
  ],
  "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
  "id": "6zbljdhqtd2oqdxxfe9tpq",
  "url": "https://api.chucknorris.io/jokes/6zbljdhqtd2oqdxxfe9tpq",
  "value": "When Chuck Norris does a pushup, he isn't lifting himself up, he's pushing the Earth down."
}

to view the headers received from the API:

curl -IL https://api.chucknorris.io/jokes/random\?category\=\{sport\}
HTTP/1.1 200 OK
Date: Sun, 31 Mar 2019 09:33:09 GMT
Content-Type: application/json
Connection: keep-alive
Set-Cookie: __cfduid=da92959d5e9e98546cce88816f1e66aa91554024789; expires=Mon, 30-Mar-20 09:33:09 GMT; path=/; domain=.chucknorris.io; HttpOnly
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With
Cache-Control: no-cache
Via: 1.1 vegur
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
CF-RAY: 4c0151f39e13ac30-JNB

resty

resty makes it simpler to call APIs, so you dont need to repeat the HTTP base path all the time. You set it once, like such:

resty https://api.chucknorris.io/jokes/random
https://api.chucknorris.io/jokes/random*

And now you simply do your operations:

GET \?category\=\{sport\}
{"category":null,"icon_url":"https:\/\/assets.chucknorris.host\/img\/avatar\/chuck-norris.png","id":"9gnFAm4uQZ2mGnDpWFb0Ag","url":"https:\/\/api.chucknorris.io\/jokes\/9gnFAm4uQZ2mGnDpWFb0Ag","value":"What is the definition of infinity? The number of people Chuck Norris has roundhouse kicked in the face."}

httpie

Httpie has the built in capability to format the json response, so no need for jq. You can also see the headers sent and received in one request:

GET /jokes/random HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Host: api.chucknorris.io
User-Agent: HTTPie/1.0.2



HTTP/1.1 200 OK
Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: Content-Type, Accept, X-Requested-With
Access-Control-Allow-Methods: GET, HEAD
Access-Control-Allow-Origin: *
CF-RAY: 4c049353eebbac3c-JNB
Cache-Control: no-cache
Connection: keep-alive
Content-Encoding: gzip
Content-Type: application/json
Date: Sun, 31 Mar 2019 19:02:04 GMT
Expect-CT: max-age=604800, report-uri="https://report-uri.cloudflare.com/cdn-cgi/beacon/expect-ct"
Server: cloudflare
Set-Cookie: __cfduid=d5388018e2f0e1d82ddde717d361901a01554058924; expires=Mon, 30-Mar-20 19:02:04 GMT; path=/; domain=.chucknorris.io; HttpOnly
Transfer-Encoding: chunked
Via: 1.1 vegur

{
    "category": null,
    "icon_url": "https://assets.chucknorris.host/img/avatar/chuck-norris.png",
    "id": "DeoesP_tQAeujKcEy9jObQ",
    "url": "https://api.chucknorris.io/jokes/DeoesP_tQAeujKcEy9jObQ",
    "value": "Chuck Norris plays bingo with a paint ball gun."
}

Here are some really good resources: