When working with remote APIs on the commandline, httpie, the well-designed commandline API client is pure bliss. For those that haven’t heard of or just didn’t know yet about httpie, this post should open your eyes to the beauty of what this little library is and its outstanding usefulness (for instance, quick-and-dirty testing your API during development)!
As an example we will talk to the remote API of our in-house redmine instance.
First of all, if we want to access our redmine API, we will need to authenticate somehow. The help page tells us of two different ways to do so, of which we will choose the latter, sending our API key in a header.
After visiting https://redmine.it-agenten.com/my/account{.uri} we now have an API key to use with httpie: APIKEYISLONG
, which we will send under the X-Redmine-API-Key
-header, as the API description suggests.
To dive right in, let’s see what is to be found under /projects.json
:
http https://redmine.it-agenten.com/projects.json X-Redmine-API-Key:APIKEYISLONG
Since adding the key to each and every command/request is a bit cumbersome, saving the session and using it in the following calls might make a lot of sense:
http --session=redmine https://redmine.it-agenten.com/projects.json X-Redmine-API-Key:APIKEYISLONG
Now, the following calls won’t need the explicit key any more and the session itself should be enough:
http --session=redmine https://redmine.it-agenten.com/projects.json
Very well, that works nicely! For a spin, let’s go to https://redmine.it-agenten.com/my/account{.uri} again, and revoke the key. The sessions should now be invalidated:
http --session=redmine https://redmine.it-agenten.com/projects.json
HTTP/1.1 401 Unauthorized
Works as expected! For the rest of the tutorial though, we will continue to use the sessions-feature so let’s quickly update the session to the current API key:
http --session=redmine https://redmine.it-agenten.com/projects.json X-Redmine-API-Key:NEWAPIKEYISLONGTOO
As a quick sidenote, the redmine API supports both XML and JSON formats:
http --session=redmine https://redmine.it-agenten.com/projects.xml
As you might guess (or have observed from the API’s responses), all of the above mentioned calls issued GET requests (use http POST :8000
to quickly POST to localhost:8000
).
Getting down to business
In the following, let us look at some of the beautiful ways, httpie lets us form our queries. How about we inspect the issues of a specific project?
Having found out the project’s id, from the calls that we have just issued, let’s drill down to the issues, and, on the way watch some more of the interactions using --verbose
:
http --verbose --session=redmine https://redmine.it-agenten.com/issues.json project_id==132
httpie offers elegant syntaxes, to distinguish the nature of the variables that you want to pass into the API. In this case, redmine expects a call to /issues.json?project_id=<project-id>
, so we use ==
in our commandline call (check httpie‘s documentation for the other types).
To be honest, we already have seen one of the other ways of setting “variables”, namely in our setting of the header, using :
by issuing X-Redmine-API-Key:APIKEYISLONG
. To cut a long story short, for all the usual cases use the following:
:
to set a header==
to set a URL parameter:=
for JSON posts=
for form encoded data
Listing all open issues assigned to me in project X:
http --verbose --session=redmine https://redmine.it-agenten.com/issues.json project_id==132 assigned_to_id==me status_id==open
Listing all issues of any type in any project assigned to me:
http --verbose --session=redmine https://redmine.it-agenten.com/issues.json assigned_to_id==me
Listing all issues assigned to me that block other issues by passing include==relations
to the call (the Redmine API actually forgot to mention this, but it works 😉 )…
Note: For one, I use --body
for httpie to not recieve any of the interactions with the server and just the pure data, and, secondly, another tool, jq to trim down the JSON returned (which will hopefully be part of another “Tool of the Week”-post).
http --body --session=redmine https://redmine.it-agenten.com/issues.json assigned_to_id==me status_id==open include==relations | jq '.issues[] | .relations'
[
{
"id": 1346,
"issue_id": 10348,
"issue_to_id": 10347,
"relation_type": "blocks",
"delay": null
}
]
[
{
"id": 1346,
"issue_id": 10348,
"issue_to_id": 10347,
"relation_type": "blocks",
"delay": null
}
]
You get the idea. Check https://www.redmine.org/projects/redmine/wiki/Rest_Issues{.uri} for more on this.
Although we haven’t even spoken about POST, PUT and the other HTTP methods (which httpie obviously fully supports) and notwithstanding we have hardly even scratched the surface of httpie‘s functionality, I hope this post has wet your appetite and you will find good uses and great pleasure in using httpie in the future.
Have a lot of fun!