Three years ago

Command-line API testing tricks

Whether building or consuming APIs, you're definitely testing out API calls. The command line is a developer's best friend for quick checks and iterative development. You can move even faster with HTTPie. HTTPie releases unintuitive command flags from your brain and removes repetitive parameters completely.

This post will give some quick examples to make the most of your command line API development. Use these tips and tricks to ease your API headaches and bring some fun into your workflow.

Make JSON a first-class citizen

For at least a decade, JSON has been the de facto standard response format for HTTP APIs. Strangely, a lot of tools give equal weight to other formats. HTTPie comes with sensible defaults, which assume data is expressed in JSON.

After the fast and easy installation you can retrieve JSON responses with a simple command line call:

$ http api.open-notify.org/astros.json

When you run this command you’ll get a list of the people currently in space, thanks to Open Notify. By default, HTTPie makes your API responses readable. The results of this call are displayed in syntax-highlighted JSON. And no need to pipe to another formatting tool or ask the server to pretty print the results.

Whether request or response data, HTTPie always looks for JSON first, unless told otherwise. That means that Content-type and Accept headers are set to application/json. It will even attempt to find JSON within text/plain or unknown content types.

As much as developers love JSON, we don’t always enjoy writing it, especially on the command line. Use flexible command line parameters to construct your JSON without curly brackets, quotes, and a lifetime supply of backslashes.

Here’s a sample call to send some basic JSON, without any of the obtrusive syntax:

$ http POST pie.dev/post name=Jason year:=2001

When you fire off that command, HTTPie interprets the field=value pair as a string and field:=value as a literal (in this case, a number). All of these parameter pairs turn into the JSON data POSTed to the URL:

{
  "name": "Jason",
  "year": 2001
}

For more complex data, you can include external JSON or text files. But you can stop struggling with JSON syntax, escaped quotes, and the like, just to express simple request data. There’s a natural progression of complexity, allowing HTTPie to handle one advanced field (say, an array) while maintaining a simple command line syntax. Refer to the JSON fields documentation for guidance on these approachable details.

Use natural API-native commands

Nothing against the other command line request tools, but they weren’t built for APIs. Some of these CLI relics have been around almost as long as the Web itself. In an effort to support every protocol, data format, and usage pattern, they can make it difficult to accomplish the everyday tasks of API developers. HTTPie was built alongside modern API development to be a natural extension of your work.

JSON as a first-class citizen is certainly an API-native choice. In addition, HTTPie pays homage to the primary protocol used to access APIs—HTTP. The interface design of many HTTPie commands mimic the underlying HTTP requests.

For example, this command:

$ http POST pie.dev/post \
    X-API-Key:123 \
    User-Agent:Bacon/1.0 \
    name=Jason year:=2001

Will be sent via HTTP as the following:

POST /post HTTP/1.1
Host: pie.dev
X-API-Key: 123
User-Agent: Bacon/1.0
Content-Type: application/json

{
    "name": "Jason",
    "year": 2001
}

Request headers are communicated almost identically, without the need for special command flags. This simplicity is made possible by a minimal DSL for request items that flows naturally. The : for headers comes from HTTP, as does = for data. In fact, the power of the syntax is clear with a simple tweak to a commend: add a -f flag and the exact same data fields will be sent form-encoded:

POST /post HTTP/1.1
Host: pie.dev
X-API-Key: 123
User-Agent: Bacon/1.0
Content-Type: application/x-www-form-urlencoded

name=Jason&year=2001

If you want to see how these HTTP calls look without making live calls, you can enter --offline mode. Rather than send a request to the host, HTTPie prints it to stdout.

Offline mode is a great way to see some of the other implicit choices HTTPie makes:

The natural syntax keeps your head in your API development and your eyes out of man pages. That lets you focus on the bigger issues, like getting API authentication to work.

Don’t repeat your authentication

You may be familiar with the DRY principle in software development. Meant to reduce repetition, DRY stands for Don’t Repeat Yourself. Typical code-level approaches include modularization and similar abstractions. By contrast, each API request stands on its own. Every time you make an API request you must include any authentication credentials, even if you sent them in a previous request. For example, if your API requests are to a cloud storage service, every request that accesses your account needs your credentials for that service. This is repetitive and inconvenient.

As an API client, HTTPie must abide by the API server’s rules. While the server must receive credentials fresh each time, HTTPie can store them to send on your behalf.

Use the session functionality, so you don’t repeat your authentication. Session functionality is convenient when you pass API tokens in headers or as part of a request URL. In either case, these get in the way of the rest of your API call.

When you make your first call, include the authentication, headers, and whatever else you want to send with every call. Then use the --session flag to give the session a name:

$ http --session=dev -a :APIKEY pie.dev/get \
  X-Random-Header:Included

Here we’ve included an API key via Basic Auth and a custom header. We also created a session named “dev.” Subsequent calls will only need to include the session flag to pass the authentication and header from the previous request.

This command has the same results as the more verbose command:

$ http --session=dev pie.dev/get

The API key authentication was attached to the HTTP call, even though we did not explicitly include it in the command. Similarly, the X-Random-Header that took up so much space is sent without being explicitly present.

Sessions make for much cleaner commands, especially when you start sending query parameters or request data. Once you have the session flag in place, you don’t repeat yourself. And you can be done with the copy-pasting or tedious command line editing that so often accompanies API tinkering.

An alternative to named sessions is to store session details within local files. You can share these session files amongst your team, so you always get the same results. Then call them up by file path, or use the trick in the next section—include them in your default configuration.

Create your own defaults

It can be an adventure to watch someone develop on their own machine. You’ll notice seemingly random key combinations produce extraordinary results (but pure chaos when a Vim user mistakenly thinks they're in insert mode). These sorts of customizations can help you get the most out of any dev tool. You’ll appreciate the custom defaults you can add to HTTPie to make it your own.

The latest configuration file options and location are in the HTTPie docs.

For example, you can enable sessions by default, so credentials and custom headers from the previous sessions are automatically sent with each request to the same host. To do this, you include the --session flag in default_options. A unique session file will then be created for each host, which you can then modify. Your config file will look something like this:

{
    "default_options": [
      "--session=default"
    ]
}

Whenever you need to overwrite the defaults, include another session flag explicitly or use a --no-session flag to ignore any existing session data.

Your config defaults can include any flag options as an array, like so:

{
    "default_options": [
      "--session=default",
      "--body",
      "--style=colorful",
      "--format-options=json.indent:2"
    ]
}

In this example, we have the session flag as before, but we also have:

  • included --body to display only the response body (no headers);
  • set the syntax highlighting --style to a defined color scheme;
  • used --format-options to set indentation equal to two spaces;
  • and instructed HTTPie to --follow redirects to a new location.

Using defaults, all of these flags will be included every time you use the http command, unless you specifically override them.

You can find a categorized list of command flags, which include options for downloading data, using SSL, and employing proxies, with the following HTTPie call:

$ http --help

Within the list, you’ll find a balance of intuitive defaults with the flexibility to make it your own.

Please note that changing default_options may lead to unexpected inconsistencies when sharing HTTPie commands with other developers. You can temporarily disable custom default_options and verify HTTPie’s default behavior by setting $HTTP_CONFIG_DIR, for example:

$ HTTPIE_CONFIG_DIR=/tmp http pie.dev/get

Get fewer API headaches

HTTPie started in 2012 to eliminate our own pain when building and calling APIs. Thousands of developers add it to their command line and use it to perform effortless requests with beautiful responses.

Learn more about HTTPie and follow us for more tips, news, and API tricks.