skip to content

Search

Getting Rid of My 2000-line api.org File

2 min read

How I replaced a 2,000-line Emacs org-mode API workflow with the VS Code REST Client extension to simplify request chaining and improve portability.

For a long time, my API development workflow lived in Emacs, inside a carefully maintained api.org file that grew to nearly 2,000 lines. Each endpoint had a dedicated section, annotated and structured using org-mode and restclient.el. It was efficient, flexible, and tightly integrated with my editor.

While Emacs is still my daily driver for note-taking, planning, and writing, the VS Code REST Client extension has quietly replaced the need for a dedicated .org file for API calls.

For example, where I used to write this in Emacs:

#+BEGIN_SRC restclient
POST http://localhost:3000/v1/something
Content-Type: application/json
{
  "name": "testing something"
}
#+END_SRC

I now write this:

### @name createSomething
POST http://localhost:3000/v1/something
Content-Type: application/json
 
{
  "name": "testing something"
}

The response can then be reused in subsequent requests without writing scripts or using tools like jq to extract values. In Emacs, this might have looked like:

#+name: get_something_id
#+begin_src restclient :results value :jq-args -r :jq .[0].id
GET http://localhost:3000/v1/something
#+end_src
 
#+begin_src restclient :var something_id=get_something_id
GET http://localhost:3000/v1/something/:something_id
#+end_src

But in REST Client:

### @name createSomething
POST http://localhost:3000/v1/something
Content-Type: application/json
 
{
  "name": "testing something"
}
 
### Get something by ID
GET http://localhost:3000/v1/something/{{createSomething.response.body.$.id}}

One unexpected benefit of this switch is how much easier it is to share endpoints with others on the team, especially when everyone uses the different tools. These .http files work well across workflows, and can even be embedded as http code blocks in Markdown to mimic the “living documentation” feel of an org file.

It’s not a replacement for org-mode, but for API workflows, the REST Client is a simpler and more portable alternative. And it helps to have your API tools and code in the same editor.

Bonus Example: File Uploads

One thing I really disliked in my old setup was having to mix restclient and shell blocks just to upload a file. For example:

#+begin_src shell :var something_id=(org-sbe get_something_id)
curl -F "file=@./something.jpeg" \
  "http://localhost:3000/v1/something/:something_id/files"
#+end_src

Using REST Client, I can now write the same thing in a single .http file:

### Upload file
POST http://localhost:3000/v1/something/{{createSomething.response.body.$.id}}/files
Content-Type: multipart/form-data; boundary=--FileUpload
 
----FileUpload
Content-Disposition: form-data; name="something"; filename="2194889204.jpeg"
Content-Type: image/jpeg
 
< ./something.jpeg
----FileUpload--

Note: According to RFC 2046 Section 5.1.1, multipart boundaries must start with --. Easy to overlook when writing by hand.