During the past few months I’ve been working on some projects that use OpenAPI to describe their HTTP interfaces. As such, I had the chance to play with the Swagger UI a lot. While I found it to be an amazing tool to experiment around with an API, one thing bugged me - I spend lots of my time in terminal, and Swagger UI is a browser app.
After some time of trying to find an existing tool, my mind turned to http-console2 - my fork of Alexis Sellier’s http-console. While it desperately needed a refactor, its interface seemed to be a prime candidate for extension with features that turn it into a full-fledged API explorer.
So, a couple of days later:
I am very pleased to announce a brand new http-console2, now supporting:
- Multiline JSON bodies
- OpenAPI-based autocompletion
- Per-origin command and request body histories
- Contexts
Feature highlights
These are the features I’m most excited about.
Multiline JSON bodies
Editing single line JSON can get very tiring, very fast. Hence, this:
OpenAPI-based autocompletion
If the API you’re chatting with supports OpenAPI, http-console2 can now discover its specification and autocomplete based on it.
To enable OpenAPI support, launch http-console2 with the --openapi
switch (and
--json
, when appropriate). For example, while interacting with Kubernetes
API:
Per-origin command and request body histories
http-console2 now supports origin-specific command and body history. This means
that if you press arrow-up when talking to http://127.0.0.1:1337
, you won’t
receive history suggestions from your session with http://127.0.0.1:7331
.
You can, however, configure http-console2 to share histories you would like to share. This is especially helpful when you regularly connect to different servers that speak the same protocol, for example your local development server, and a remote development server:
$ http-console2 --history rabbits-dev 127.0.0.1:8000
...
$ http-console2 --history rabbits-dev https://api.dev.rabbitshq.com
# http-console2 will propose commands from your session with 127.0.0.1:8000 here.
...
Contexts
This is probably my second favorite feature in this release, right after the OpenAPI-based autocompletion, simply due to how often I need to talk to several versions of the same service, running in different environments.
Contexts are a way for http-console2 to deduce some common settings based on the
URL you’re talking to. To reuse the local and remote development server example,
you can place the following in ~/.http-console2/contexts.json
in order to
implicitly configure http-console2 with --openapi --json --history rabbits
when
you run http-console http://127.0.0.1:8000
or http-console https://api.dev.rabbitshq.com
.
{
"rabbits": {
"urls": ["http://127.0.0.1:8000", "https://api.dev.rabbitshq.com"],
"openapi": true,
"json": true,
"history": "rabbits-dev"
}
}
Installing
Sounds interesting?
Give it a whirl!
npm install -g http-console2
http-console <url>
The refactor
This is a deeper dive into the refactor and some of the technical decisions made along the way. Feel free to jump straight to conclusions.
Work organization
I’ve started this refactor knowing clearly what I wanted to achieve:
- basic UX same as http-console
- but with more “API explorer” flavor
- and OpenAPI support
Based on those I made a plan - funemployment rendered me with lots of time on my hands, and I was going to do my best to not let feature-creep creep me out of this refactor.
Looking back, I’m very happy with the scope I’ve set, and with the outcome that realizing this scope had brought.
Refresh
The first step was to refresh the ~9 year old codebase (I haven’t been the best maintainer).
I’ve been on a binge of trying out different new node.js HTTP clients, and
I decided to use got
for this project (instead of the core http
module,
as the original http-console does). That turned out to be a huge time saver,
and I came to enjoy its API very much.
I also migrated from using the readline
module to the repl
module. It felt
more appropriate, and gave us a couple of features for free (like REPL commands,
or easy acceptance of multiline JSON bodies).
Autocompletion
I wanted to accomplish both URL and request body autocompletion, based on both history and OpenAPI spec, if available.
Setting up the barebones turned out to be easy, thanks to the the repl.start
’s completer
parameter.
Providing request body completion proved to be more tricky. It involved setting up stream-json
so that it extracts the current JSON path user is typing at the
time of end of input, and flattening OpenAPI schemas
into something less complex, and easy to pick at from the completer’s perspective.
Overall, this was the most challanging, but also the most fun part of this project.
An interesting fact I learned along the way was that Kubernetes’ API specification has cycles in it.
Conclusions
I am very happy with the 0.9 release. It satisfies all the requirements I had for it, and is already proving to be very useful. Additionally, I had a lot of fun writing it, as I enjoy writing developer tools.
Plans for the next version
My plans for the next release are to make this a, well, more effective REPL.
I’d like to be able to run crude operations on the data returned - pick at them
(preferably with JSONPath/jq
/etc. style path expressions), feed them to next
operations, write them to files, etc.
I also intend to make the OpenAPI completion smarter, give it an understanding of arrays and a way to preview the schema - perhaps by double-pressing Tab when having a fully completed URL.
Thank you for reading, and stay tuned for updated!