CacheLane Logo

Chapter 06

Adding HTTP methods to the Router

In this exercise, we will improve our TrieRouter API by implementing support for HTTP verbs (GET, POST, PUT, DELETE, etc.) directly instead of using raw strings. Let's look at our current implementation of the TrieRouter:

trieRouter.addRoute("GET", "/users", () => {});
trieRouter.addRoute("GET", "/", () => {});

As you could already feel, this approach is not very flexible and uses raw strings, which can lead to typing errors, and has no auto-completion support unfortunately. Let's improve this by adding support for HTTP methods directly to the TrieRouter API.

Update the TrieRouter class

const HTTP_METHODS = { ... };

class TrieRouter {
    ...

    #addRoute(path, method, handler) {
    ...
    }

    get(path, handler) {
        this.#addRoute(path, HTTP_METHODS.GET, handler);
    }

    post(path, handler) {
        this.#addRoute(path, HTTP_METHODS.POST, handler);
    }

    put(path, handler) {
        this.#addRoute(path, HTTP_METHODS.PUT, handler);
    }

    delete(path, handler) {
        this.#addRoute(path, HTTP_METHODS.DELETE, handler);
    }

    patch(path, handler) {
        this.#addRoute(path, HTTP_METHODS.PATCH, handler);
    }

    head(path, handler) {
        this.#addRoute(path, HTTP_METHODS.HEAD, handler);
    }

    options(path, handler) {
        this.#addRoute(path, HTTP_METHODS.OPTIONS, handler);
    }

    connect(path, handler) {
        this.#addRoute(path, HTTP_METHODS.CONNECT, handler);
    }

    trace(path, handler) {
        this.#addRoute(path, HTTP_METHODS.TRACE, handler);
    }
    ...
}

Explanation

Firstly, we've added dedicated methods for each HTTP method in the TrieRouter class. This allows users to define routes more intuitively using method-specific calls like trieRouter.get('/home', handler) for the GET method and trieRouter.post('/home', handler) for the POST method.

In each of these methods, we call the existing addRoute method, passing the appropriate HTTP method from the HTTP_METHODS object.

This change allows for a consistent and clear way to find routes based on the HTTP method.

Sedcondly, we've made the addRoute method private by prefixing it with a #. This means that the #addRoute method can now only be accessed from within the TrieRouter class and not from outside.

Now, to test the new API, let's update our previous example:

const trieRouter = new TrieRouter();

trieRouter.get("/users", function get1() {});
trieRouter.post("/users", function post1() {});
trieRouter.put("/users", function put1() {});
trieRouter.delete("/users", function delete1() {});

console.log(trieRouter.findRoute("/users/e", HTTP_METHODS.GET)); // null
console.log(trieRouter.findRoute("/users", HTTP_METHODS.POST)); // function post1() {}
console.log(trieRouter.findRoute("/users", HTTP_METHODS.PUT)); // function put1() {}
console.log(trieRouter.findRoute("/users", HTTP_METHODS.TRACE)); // undefined

Looks good, and now we have a more intuitive way to define routes based on HTTP methods. Let's move on to the next exercise to add support for route parameters.

Previous
Ex. Adding HTTP method support