skip to content

Search

Getting rid of my 2000-line api.org file

2 min read

A look at how I replaced a 2,000-line Emacs org-mode API workflow with the VS Code REST Client extension, simplifying request chaining, improving portability, and reducing friction in my development loop.

For a long time, my API development workflow lived inside Emacs — specifically in a carefully maintained api.org file spanning 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.

But recently, that file has become… redundant.

While Emacs remains 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 using its id — no scripting or postprocessing with jq needed. 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 since not everyone uses the same 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, it’s a simpler, more portable alternative that gets out of the way.

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.