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.