curl for REST API requests


misc utils shell command-line

This post discusses how to use curl for making REST API requests from the command line. curl is an open-source tool for transferring data that supports protocols like HTTP, FTP among others. For demonstrating the usage of curl, we will be hitting a public REST API hosted at typicode - We are going to play around with the posts resource in the above API. Since we aren’t setup anything locally, just copy-pasting the below-mentioned snippets to your shell should work automatically. Let’s dive right in, without further ado.


GET request

GET requests are the simplest to make. We just need to pass the API URL as the argument to the curl command.

curl https://jsonplaceholder.typicode.com/posts

Any path param can be appended to the URL - The following request fetches posts with id as 1

curl https://jsonplaceholder.typicode.com/posts/1

We can also use query params with the request, by adding them to the URL - The following fetches the posts with userId as 1

curl https://jsonplaceholder.typicode.com/posts?userId=1

We can use mutiple query params separated by an &(ampersand), but the URL string needs to be enclosed within double quotes in this case. The reason is that & is also used to start background jobs from the shell - Without the quotes, the shell would think that it is the end of the command (thereby stop reading the other query params ), and run the curl command in the background.

curl  "https://jsonplaceholder.typicode.com/posts?userId=1&id=6"

One thing to note is that, for the POST/PUT/DELETE requests here, the resource will not actually be modified on the server, but will be faked as if it is. Also, (for clarity) the commands are split into multiple lines - if you are copy-pasting from here, please merge into one line(remove line breaks) before trying out the command on the shell/terminal.


POST request

The following is a sample POST request using cURL. The meanings for the different arguments are explained below.

curl -H 'Content-Type: application/json' 
-d '{"userId":1,"id":1,"title":"sample title","body":"sample body"}' 
-X POST https://jsonplaceholder.typicode.com/posts

-H - Used to denote the request headers (cURL uses application/x-www-form-urlencoded as the default Content-Type , when used with the -d parameter. For JSON APIs, we need to the explicitly pass application/json as the Content -Type).

-d - Denotes the request data (API payload). Since the request payload contains double-quotes, the payload need to be enclosed in single-quotes.

-X - Request type (POST, PUT, DELETE, etc)

In case you need to pass multiple headers, use the -H parameter multiple times. For example,

curl -H 'Content-Type: application/json' -H 'My-Header-Name: My-Header-Value' 
-d '{"userId":1,"id":1,"title":"sample title","body":"sample body"}' 
-X POST https://jsonplaceholder.typicode.com/posts

You can also store the request payload in a file and use it with curl, as shown in the next section.


PUT request

curl -H 'Content-Type: application/json'
-d '{"userId":1,"id":1,"title":"sample title","body":"sample body"}' 
-X PUT https://jsonplaceholder.typicode.com/posts/1

The PUT request is very similar to the POST example above, with a couple of minor tweaks:

  • Pass PUT as the request method (for the -X option)
  • PUT is used to update an existing resource, so the id of the resource needs to be passed in the URL

PATCH Request

The PATCH request is very similar to PUT, except that we need to specify PATCH as the request method for the -X option.

curl -H 'Content-Type: application/json' 
-d '{"userId":1,"id":1,"title":"sample title","body":"sample body"}' 
-X PATCH https://jsonplaceholder.typicode.com/posts/1

HTTP DELETE request

For DELETE APIs, we need to use DELETE as the argument to -X. Delete APIs don’t require a payload or header normally, so can skip the -d and -H options as below:

curl -X DELETE https://jsonplaceholder.typicode.com/posts/1

Gotchas!

Now that we have covered how to make API requests using cURL for different HTTP methods, it’s time to enhance our expertise with some neat little capabilities cURL provides.

Read from file

We can pass a file containing the request payload to the -d option, as below (Create a file named request.json in the current directory and add the request payload, before trying out the command):

This option is extremely useful especially when dealing with large request payloads.

Write to file

It is also possible to write the response body to a file using the -o option - The command below creates a file named response.json and writes the response payload to it.

If we would like to read request from file, and write response to file:

Verbose Output

For the API requests we have been trying out so far, cURL outputs only the response payload to the console - It doesn ’t provide any information on the status code of response, response headers, etc. The -v option solves this use case - It prints out the HTTP status code, useful request + response headers (Content-Type, Content-Length, cookies, etc ) which comes in handy while troubleshooting issues.

Format Json

And last but not the least, we can pretty-print the response json, as below (Should work as long as you have Python installed on your machine):

The jq tool, supports a multitude of other options(extracting certain elements from payload, etc) in addition to pretty-printing, but you have to take the pain of installing it.

curl  https://jsonplaceholder.typicode.com/posts/1 | jq '.'

Conclusion

We can also use tools like Postman or Insomnia to invoke REST APIs. They provide advanced features like collections, collection-runner, history, etc.However, if you are a command -liner and wanna try an API quickly without taking your hands off the keyboard, the curl utility is your best friend. I hope you found the post useful 😄 Thanks for reading.


See Also