First Look at Thunder Rest

Tags:  Neovim  Rest.nvim 

After a long time of decision-making and changes, it will soon be ready and completely stable to be used publicly!

Introduction

Exactly a week ago I made the announcement of the new version of the tree-sitter parser for HTTP files that needed the rewrite of rest.nvim as its backend. Now, we also have the first working version of v2 of rest.nvim!

I’m really very excited to announce this, especially because personally it is proof that I was finally able to get out of the burnout I had for a while and also I finally feel good about programming. I hope you like everything you will see here as much as I do, although there are also some small features that had to be abandoned from rest.nvim, at least temporarily. :(

If you have any opinion about the post, you can let me know through my different forms of contact, ko-fi (if you donated to the project 💜) or Reddit because this post will most likely end up shared there. Your opinion would be very pleasant to me, and I would be very happy to answer any questions about it. :D

Notes:

  1. There are some small things missing and others that I don’t consider completely finished yet as I would like, so some things will be subject to change.

  2. I’m going to divide the main post content into two parts like any good full-stack programmer; front and back.

Requirements

First of all, let’s talk about what is most serious for you as a user, the plugin requirements.

Neovim

rest.nvim has been rewritten completely from scratch (and no, I’m not kidding). Due to this, every possible new Lua API in Neovim has been taken advantage of, raising the version requirement to the latest stable version of it (>= 0.9.x). If you are using an older version, I strongly recommend that you update your version of Neovim.

Dependencies

If you saw the rewrite roadmap (if not, I recommend seeing it here) you may have noticed that in the installation section we talked about luarocks, dependencies, etc. All this is very necessary for the proper functioning of rest.nvim and is completely mandatory.

We’ve also been working for months on a new manager plugin for Neovim that revolves around luarocks, called rocks.nvim, which I mentioned is the new preferred installation method for rest.nvim due to the fact that which prioritizes luarocks (it can even install it for you and have everything self-contained!), and doesn’t get in your way in any way

Installation using lazy.nvim in conjunction with luarocks.nvim is also possible, but it will not be recommended since I am using rocks.nvim in my daily life so I cannot support installation problems with lazy.nvim (sorry guys, I will try to at least provide installation instructions for it!).

Currently the Thunder Rest release has 4 external dependencies, which are the following:

All these dependencies are necessary for rest.nvim to work as it should and to cover all your possible development needs, I recommend you take a look at them. :P

The front-end

This being the front, we will see more than anything what you see as a user when using rest.nvim. I don’t think I cover absolutely everything in this category, but I will try to cover the most relevant!

Rest command

Let’s welcome the :Rest command, which will lazily join the party to help us manage our environment with rest.nvim!

Rest command showcase

The :Rest command will allow us to run our requests, change our env easily and navigate through the new requests results window.

This command has autocompletion for all its subcommands and arguments, as well as very rich error handling so you won’t have a hard time with it, at least that is what I hope! :P

Note: The :Rest run document is not yet implemented, please be patient!

Request results

This will be completely amazing if you have already used rest.nvim before, because believe me, it is a very impactful change.

After some small talk with a colleague and a couple of brainstorms, it was decided that a winbar (:h 'winbar') would be used for the results of the requests with different panels to contain the information, in a kind of categories.

It actually sounded a bit complicated to implement for me, but luckily he had something like this done in one of his plugins (stuff.nvim) so he let me take the code and then mold it according to the needs of rest.nvim (and obviously, he took the credits in the commit :D). This is the result

rest.nvim results showcase

It looks good, doesn’t it? You can navigate each of the panels by clicking on it (or using H and L, if you’re more attached to your keyboard) or using the :Rest result command interface.

Notes:

  1. This is still in progress, it may undergo some minor aesthetic changes later.
  2. The right side statistics may not display well in small windows.

Keybinds and help

As you may have seen in the image, on the right side of the winbar there is a small hint to get help. This will be a window that will show you the keybinds of the results window, it is not yet implemented but it is in progress :P

However, I leave you a list of the current keybinds for the moment:

  • H - go to the previous pane
  • L - go to the next pane

Note: This is still in progress, it’s not completely finished and working the way I want but I hope to finish it this week!

The back-end

Now, let’s move on to the back side, which is really very interesting and leaves nothing to be desired.

Here we will see the internal functioning of parsing, how the new cURL runner works, how they plan to integrate additional clients to cURL in the form of extensions, etc.

API

Yes, rest.nvim now exposes a public API in the rest-nvim.api module, albeit dedicated to those who want to expand rest.nvim in some way or develop support for external clients.

For now this API only allows creating autocommands in the Rest augroup and adding new commands to :Rest (e.g. :Rest foo), however I hope it will be a much more useful API in the future :)

Parsing

This is perhaps the heaviest part of all, in fact, the one that has taken the most work and time.

Taking a total of 352 lines of code at the moment, the parser module is almost 100% finished, missing little things like HTTP forms or full support for GraphQL requests. And don’t worry, even though those things are missing, it is fully functional and will cover almost all your needs.

Progress on this module has been really nice and fast thanks to the rewrite of the HTTP tree-sitter parser, so likewise the missing things will be implemented quickly, except for GraphQL support which will take a bit more than time.


The parser is currently responsible for producing a Lua table with each important element self-contained as can be seen below along with its annotations.

rest.nvim parser module main function

This table is returned and serves to feed the HTTP client that the user is using (cURL by default). In this way, it is expected to be able to add other clients and alternatives to cURL externally without complications by providing consistent information to all of them.

cURL client

The new cURL client is native Lua bindings around libcurl. This means, we have a native, fast and robust, error-proof interface.

This has greatly reduced some of the boilerplate that had to be done previously, and makes the job a lot easier compared to the wrapper around the curl binary that has plenary.nvim, which really couldn’t currently meet all the needs of rest.nvim due to its complexity. Thanks for everything, plenary.nvim!

Third-party clients

This point will not have much explanation because we already know part of the implementation from the information above and the specifications have been explained as well here.

However, the structure has changed a bit to add consistency and reduce complexity with the core rest.nvim. Previously this was the proposed structure:

lua/
└── rest-nvim/          # Root rest-nvim module directory
   └── add-ons/         # Add-ons directory so we can require("rest-nvim.add-ons.foo")
      └── postman/      # Postman CLI add-on module directory
         ├── init.lua   # Postman CLI add-on module init file
         └── utils.lua  # Postman CLI add-on module utilities file

And it’s not bad, so the only change was to rename the add-ons directory to client, looking like this:

lua/
└── rest-nvim/          # Root rest-nvim module directory
   └── client/          # Client directory so we can require("rest-nvim.client.foo")
      └── postman/      # Postman CLI add-on module directory
         ├── init.lua   # Postman CLI add-on module init file
         └── utils.lua  # Postman CLI add-on module utilities file

What is missing?

Unfortunately, there are some things missing, either because they have been removed or because they don’t exist yet, let’s take a look at them!

Removed features

Unfortunately some features have had to be removed, due to the nature of the new cURL client (we are not running curl foo commands anymore). These features are the following:

  • The possibility of previewing requests cURL commands
  • The ability to copy the cURL command that has been executed to the clipboard

New features

Some new features will be added to rest.nvim, either before the stable release of v2.0 or during the course of v2.x. These are some of them:

  • Add a :Rest log command
  • Add support for images through image.nvim for requests that return a picture
  • Add support for GraphQL

Final notes

This version is not yet available as a stable version, so there are no specific installation instructions yet and it is not uploaded to luarocks in case you are using a compatible plugin manager. However, the final tests will be done very soon to make a release so that you can enjoy these and many more changes and improvements.

However, if you want to try the “beta”, you will need to install the plugin using the dev branch, install the new dependencies manually using luarocks or installing them using :Rocks install if you are using rocks.nvim, and use the next branch of the tree-sitter parser. Yes, it’s a little tedious, but it’s totally worth it and it would help me a lot if you have enough time to do some stress tests!


And finally, a big thank you to everyone who helped me in any way, whether with donations, guidance with the code (especially with tree-sitter, I’m a bit stupid when it comes to parsers lmao) and more. This wouldn’t have been possible if it weren’t for you! :D 💜