Using curl for API testing
By: Dmitry Yakimov
Tags: Postman, Development, API, Terminal, Curl

I’ve found an alternative to rest clients for API testing, and I thought to share it with you. But first an intro.

Back in the days, although I’ve been using terminal extensively, I still was using Postman for making requests. I guess I just didn’t really understood how they work, and curl or wget seemed to me a little bit complicated. Especially since I was using them directly from terminal, and I had to adjust arguments all the time, and, you know, it’s not very comfortable.

Then I’ve discovered restclient for emacs. Which essentially allowed to do the same as Postman, but it was more comfortable, because I didn’t have to quit my favorite editor and I could resolve everything just by typing in the necessary commands.

But, then I thought, there has to be a better way. Why not just have a shell script file with several curl commands in it. You can edit it with your favorite editor and easily share it with anyone. Because shell&curl are common among all programmers, and they are editor-independent they can be understood by anyone, and they don’t force to use you certain app. That’s a win.

Curl Crush course

If you’ve been using apps for requests before you might want to learn a little bit about curl . It’s actually very easy for the most of the daily jobs. Here comes a little crush course, to get you aboard.

For the most of the time you can use this command:

curl -X <method> <url> --header <header> -d <data> --verbose

Where:

<method> — HTTP request method, can be GET , POST , PUT , DELETE , and others;

— HTTP request method, can be , , , , and others; <url> — the url of an endpoint;

— the url of an endpoint; <header> — request headers, you can specify several of them;

— request headers, you can specify several of them; <data> — request body, you can provide your json here

— request body, you can provide your json here --verbose — an option to show request verbosely, can be used to show the headers;

Example:

And this example becomes a building block for our api testing suit. Although it has some boilerplate with headers and explicit json, since it will be copy pasted several times it doesn’ bring much worries.

It’s that easy.

Organization

When I come to the project I usually create a file called ./requests with this boilerplate:

#!/usr/bin/env bash # Functions # Variables URL="" # Samples

Now let’s create our first API call for user log in

#!/usr/bin/env bash # Users usersLogin() {

email=$1

password=$2 curl -X POST \

"$URL/users/login" \

--header 'Content-Type: application/json' \

--header 'Accept: application/json' \

-d '

{

"email": "'"$email"'",

"password": "'"$password"'"

}'

} # Variables URL=" http://localhost:3001/a pi" # Samples usersLogin ' f rog@example.com' 'fishfish' | jq

As you can see with this structure you can define your variables. It is pretty readable, and yet universal.

Note the inserted variables here "'"$email"'" , it’s a little weird but works, and I use it here primarily to avoid extra slashes.

Also note, I use jq for json highlighting. But you can use fx or just leave it without it.

Now I just have to run the script ./requests . And I get this output:

{

"token": "eyJhbGci.eyJpZCI6.Ag2Q2hTV",

"userId": 1

}

Nice. Now, let’s add one more method:

#!/usr/bin/env bash # Users usersLogin() {

email=$1

password=$2 curl -X POST \

"$URL/users/login" \

--header 'Content-Type: application/json' \

--header 'Accept: application/json' \

-d '

{

"email": "'"$email"'",

"password": "'"$password"'"

}'

} usersFindById() {

id=${1:-1} curl -X GET \

"$URL/users/$id" \

--header "Authorization: Bearer $TOKEN"

} # Variables

TOKEN="$(usersLogin ' URL=" http://localhost:3001/a pi"TOKEN="$(usersLogin ' f rog@example.com' 'fishfish' | jq -r .token)" # Samples

usersFindById 1 | jq #usersLogin ' f rog@example.com' 'fishfish' | jqusersFindById 1 | jq

Now as you can see, I’ve created TOKEN variable, which uses previous request. And then I use this variable in the usersFindById request.

Also I provide default value for id variable via id={1:-1} , so if it is undefined it would be equal to 1 .

I get this output:

And then adding more and more requests I get a neat file, which I can use anytime for debugging.

./requests

Conclusions

There is a reliable and easy way to use command line to test your API requests. And there are several benefits in doing so: