DEV Community

Cover image for A CLI for REST APIs
Daniel G. Taylor
Daniel G. Taylor

Posted on • Edited on

A CLI for REST APIs

Standardizing how power users and scripts interact with your service

Sorry about the acronym soup in the title! 😅

Today I want to talk about an oft-neglected aspect of building REST or HTTP APIs. There are plenty of articles about API design, API description formats like OpenAPI, and lots of libraries and code generators used to talk to the API from code. What is missing in my opinion is a high-quality command line client that’s generic enough to be used for most HTTP APIs.

But there’s curl, you say. Many service docs even include examples specifically for calling the service’s API via curl commands. I love curl and HTTPie, but these are just generic HTTP clients. There’s not enough specialization for REST or HTTP APIs. HTTPie comes close since it speaks JSON, the lingua franca of web APIs, but falls short in other ways, such as describing complex inputs for API operations.

What fancy-pants features would make me happy, you ask? My list would include at least the following:

  • Easy to install & fast startup
  • Default to HTTP/2 (with TLS), which is now 5 years old! 😮
  • Speaks JSON, YAML, and their binary relatives natively
  • Caching of responses when appropriate headers are set
  • Built-in common API authentication mechanisms like OAuth 2
  • Automatically handle pagination of collections
  • An easy way to input complex nested data
  • Pretty colorized output with the ability to filter built-in
  • An understanding of API specs like OpenAPI with auto-discovery
  • Always having access to the latest API features & docs

I think that would be a good start to getting where we should be in 2020. With that in mind, I’d like to introduce my new CLI tool for REST & HTTP APIs called Restish (https://rest.sh/).

Restish logo

Restish can do all of the above wish list, and more. Installing it is easy if you have Homebrew:



$ brew tap danielgtaylor/restish && brew install restish


Enter fullscreen mode Exit fullscreen mode

Windows users will need to download a release. At its most basic it can be used very similar to how you might use curl:



$ restish -H Authorization:abc123 api.example.com/items/1
HTTP/2.0 200 OK
Content-Encoding: br
Content-Type: application/json
Date: ...

{
  name: "Item number one"
  cost: 12.34
  created: "2020-01-01T12:00:00Z"
  tags: ["grocery"]
}


Enter fullscreen mode Exit fullscreen mode

The real magic happens when you register an API base URI with Restish through the interactive configure sub-command:



$ restish api configure example
? Base URI [? for help]: https://api.example.com
Setting up a `default` profile
? Select option for profile `default` Add header
? Header name Authorization
? Header value (optional) abc123
? Select option Save and exit

$ restish get example/items/1
...

$ restish post example/items name: Another, cost: 2.50, tags[]: household
HTTP/2.0 201 Created
Location: /items/2


Enter fullscreen mode Exit fullscreen mode

If the API provides an OpenAPI spec via a known link relation header or some common path like /openapi.json then things get even more interesting because you can directly call described API operations rather than specific URIs:



$ restish example create-item name: Another, cost: 2.50, tags[]: household
HTTP/2.0 201 Created
Location: /items/3


Enter fullscreen mode Exit fullscreen mode

The popular FastAPI Python library provides exactly that, so any services written with it will just work out of the box with Restish. And because Restish loads the OpenAPI spec on the fly, whenever you push updates to your FastAPI service then your CLI users will already have the new features available.

Even better, CLI users can query the API for information on structure, including any updates you push to the API. For example:



$ restish example create-item --help
Create a new item in the inventory

# Request Schema (application/json)

{
  name*: (string) The item name
  cost*: (number min:0) The cost of the item
  tags: [
    (string maxLen:12) Tag name
  ]
}

# Response 201

A new item has been created. The `Location` header links to the item.

Usage:
  restish example create-item ...

Example:
  restish example create-item name: string, cost: 1.0, tags[]: string
  restish example create-item <input.json
...


Enter fullscreen mode Exit fullscreen mode

This is win-win for everyone. Users get a high quality CLI tool with advanced features built-in to interact with your service. Your developers don’t have to waste time building and maintaining a custom CLI or getting users to upgrade to access the newest API features.

You should consider adopting Restish for your APIs and adding the “Works with Restish” badge to your documentation.

Works with Restish

There is a ton more breadth and depth to Restish. This quick introduction is just the first of a multi-part series to go into the various features and use-cases with lots of examples, so stay tuned and thanks for reading!

Top comments (4)

Collapse
 
chen profile image
Chen

This looks like a great project! great job and thanks for sharing this

Collapse
 
ed3899 profile image
Eduardo Casanova

My recommendation would be to add a translation layer from your API to RAW curl code.

That could potentially breach the gap between old school and new school.

Especially hardcore Linux users

Collapse
 
pacogomez profile image
Paco Gómez

Congrats on your work, I plan to use restish from now on

Collapse
 
stuartnankai profile image
Jian Sun

Hi Daniel!
It looks like restish is the tool which I am looking for. Do you mind having more discussion about OpenAPI 3 Anatomy? I have questions for this part :)