Lesson Tuesday

Postman is an easy, user friendly way to test API calls. However, it's also possible to make API calls from the command line. It's not as pretty or easy on the eye to use cURL.; the command line rarely is. However, it's important to know about cURL because it's an important and very common command line tool. You aren't expected to test API calls with cURL (you can continue to use Postman if you wish), but take some time to practice making some API calls in the command line.

This lesson will go over the basics of making an API call with cURL, a few options we can pass into cURL, and a simple use case for how cURL can help you debug an API call.

cURL

cURL is a command line tool to "transfer data from or to a server" using supported protocols such as HTTP. Where did that definition come from? Go to the terminal and type the command $ man curl. This will bring up the cURL manual.

Take a quick look at the introduction as well as the various options that can be used with cURL. Wow, that’s a bit overwhelming. Type q to exit the manual and return to the terminal.

You're not expected to know most of these options right now. Just be aware that cURL is a very powerful command line tool that has a lot of built-in functionality.

We'll go over three cURL commands in this lesson: -H, -X and -d.

Using cURL to Debug API Calls

Let's start with a simple cURL command that includes no options:

 $ curl "https://www.epicodus.com/"

This spits out the HTML source code on Epicodus' home page!

An API call really isn't that different from other HTTP (or HTTPS) requests. The main difference is that we'll usually get a JSON response instead of HTML. (An API won’t always return a JSON response - there are other formats such as XML - but JSON is very common.)

Let's test this with the Open Weather Map API. We’ll use cURL to query the API in the command line and return the current weather in Portland, OR:

$ curl "http://api.openweathermap.org/data/2.5/weather"

Here's the response:

{"cod":401, "message": "Invalid API key. Please see http://openweathermap.org/faq#error401 for more info."}

A 401 code means "unauthorized." The error message makes the problem clear. Uh-oh. We forgot to pass in an API key. Let's fix that.

$ curl "http://api.openweathermap.org/data/2.5/weather?appid=[your API key here]"

And the response:

{"cod":"400","message":"Nothing to geocode"}

We’re still not getting what we want, but the error is clear. A 400 code means we've made a bad request. Once again, the error message gives us additional detail. There's nothing to geocode. Ah, we've forgotten to pass in a query. Let's fix that error, too.

$ curl "http://api.openweathermap.org/data/2.5/weather?q=Portland,us&appid=[your API key here]"

Here's our response:

{"coord":{"lon":-122.68,"lat":45.52},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"},{"id":701,"main":"Mist","description":"mist","icon":"50d"}],"base":"stations","main":{"temp":286.17,"pressure":1014,"humidity":100,"temp_min":284.15,"temp_max":289.15},"visibility":4023,"wind":{"speed":3.56,"deg":214},"clouds":{"all":90},"dt":1489513980,"sys":{"type":1,"id":2963,"message":0.1734,"country":"US","sunrise":1489501380,"sunset":1489544210},"id":5746545,"name":"Portland","cod":200}

The weather for Portland, OR has been returned along with the HTTP code 200, which means the call was successful. We could now parse this data in our application.

You should familiarize yourself with universal HTTP codes such as 200, 400 and 401, as they are an essential part of HTTP requests.

Our errors were pretty obvious, but it's often more painful to debug a dysfunctional API call in your application - especially if you've already built application functionality around an API that isn't working properly. Test the call first, then build the code!

Adding Options to cURL

Let's explore a few additional options in cURL. We could make our Open Weather API call like this instead:

$ curl -X GET -H "Accept: application/json" "http://api.openweathermap.org/data/2.5/weather?q=Portland,us&appid=[your API key here]"

We add the option -X, which specifies the custom request method. Adding the request method isn't necessary for this API call because cURL defaults to GET, but you can add -X for other request methods such as POST and PUT. Check out the documentation for -X in $ man curl.

We also add the option -H, which specifies the headers for the API call. Specifically, we're asking the server to return data in JSON format. The Open Weather API is already returning JSON format so this header isn’t strictly necessary, either. However, it's very common to pass in headers for API calls.

The third option we'll cover is -d. This option specifies data that should be sent to the server via the request body. When the -d option is added to a cURL request, the request will automatically default to POST instead of GET. You can still specify other types of requests with -X such as PUT if necessary.

Let's say we wanted to post a schoolname to an API. We might do something like this, where [APIURL] is the URL of the API call itself:

$ curl -X POST -d "school_name=Epicodus" "[API_URL]" 

This would post the school_name field to the requested API_URL. (While the -X option isn’t technically necessary here, it’s added for clarity.)

We could - and probably should - take this a little further, since we're often working with JSON. We can make the same request with a JSON object like this:

curl -X POST -d "{\"school_name\":\"Epicodus\"}" "[API_URL]"

While cURL is a very useful tool, it does have its shortcomings. For instance, it's difficult to read longer JSON responses in the command line. We also have no way to save our API calls and configuring more complex API calls could get tedious quickly. That's where Postman comes in handy. However, imagine that you wanted to write a command line script which makes an API call. In that case, cURL to the rescue!