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 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
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"]
}
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
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
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
...
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.
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)
This looks like a great project! great job and thanks for sharing this
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
Congrats on your work, I plan to use restish from now on
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 :)