A few weeks ago, I was surprised when I was asked to demo a webservice that I wrote. Since I didn't prep a Postman config for it (because I don't use Postman unless I have to, like during demos ) I got out Emacs and opened the orgfile that I had used to test the service. Suddenly the Architect piped in and said, "Emacs? Who uses Emacs to test services? I really can't stand people who use command line tools!". What he didn't know is that I wear comments like that as a badge of honor. So let me teach you how use Orgmode as a RestClient to annoy your co-workers just like I do!

There are lots of links out there how to set this up and how it works. Mike Zamansky has a great post/video of the basics of RestClient. For the OrgMode part, you basically need to use the Babel functionality and ob-restclient. This sounds like a lot of work but Doom Emacs (the config distro that I'm currently using) has all of this included.

At it's most basic, you can just do this:

#+begin_src restclient
GET http://openlibrary.org/api/volumes/brief/isbn/9781429992800.json


Enter Ctrl-c Ctrl-c (or C-c C-c as an Emacs person would write it) anywhere in that source block and it will execute. The result will be a long-winded response around a #RESULTS: section that magically appears below it. OpenLibrary has a nice API in that you don't have to specify a content type (or even an API key). Here is how you set some headers, via this sample API.

#+begin_src restclient
GET https://airport-info.p.rapidapi.com/airport?iata=OMA
x-rapidapi-key: <some key>
x-rapidapi-host: airport-info.p.rapidapi.com


You will then get the information of the Omaha airport back. Note that the headers appear directly below the GET url line. Note that you can also replaced GET with POST, PUT and etc.

If you need to put in a payload, you don't need to do fancy JSON things, just put in the string with a blank line between the headers and the payload, like so:

#+begin_src restclient
POST https://airport-info.p.rapidapi.com/airport
x-rapidapi-key: <some key>
x-rapidapi-host: airport-info.p.rapidapi.com


(Note that the above won't work, but it's still a good example)

All this is well and good, but isn't very real-world. What if you have to authenticate? What if you have to specify a content type? Well you can send the results of one evaluation to another. That document is hard to follow but essentially you can evaluate an OrgMode source block and put the results in another. You basically put it in a variable that you carry from block to block. And it doesn't matter what language the blocks are written in.

So here is an example of using Python's requests library, which makes getting an oauth token pretty easy. Note the :results token in the header – that declares a variable to put the result in.

#+begin_src python :results token

import requests

data = {"client_id": "<client id>",
"client_secret": "<some creds>",
"grant_type": "client_credentials"


r = requests.post('https://some-url/oauth/token', data = data, verify=True) #False if you have weird SSL stuff
return r.json()["access_token"]


And then you declare the token as a variable on requests and use it in the block – note the :token in the Authorization header:

#+begin_src restclient :var token=token
POST https://some-app-url/path/to/api/thing
Content-Type: application/json
Authorization: Bearer :token



So run C-c C-c on the first (python) source block and then again on the second. Boom – your call to the service it authenticated . I find this a lot easier than using alternatives.