[![Read Prev](/assets/imgs/prev.png)](/chapters/ch06.02-the-router-class.md)

## Improving the `Router` API

<!-- Buildig a backend framework with 0 dependencies with Nodejs - improving our API. Simplify route handling with new utility methods for GET, POST, and more. Enhance code readability and efficiency.-->

The utility method on the `Router` class - `addRoute` is a bit too verbose. You need to specify the HTTP method as a string. It would get tedious when there are suppose hundreds of API routes in an application. Also, devs might not know whether the HTTP methods should be sent in lower-case or upper-case without looking at the source.

Let's abstract that functionality away from the developer, making sure the developers only need to worry about the important pieces.

Current way to add routes:

```js
// file: index.js

class Router {
    constructor() {
        this.routes = {};
    }

    addRoute(method, path, handler) {
        this.routes[`${method} ${path}`] = handler;
    }
    ...
}
```

Let's add two new methods named `get` and `post`, and add some type checks in the `addRoute` method:

```js
// file: index.js

const HTTP_METHODS = {
    GET: "GET",
    POST: "POST",
    PUT: "PUT",
    DELETE: "DELETE",
    PATCH: "PATCH",
    HEAD: "HEAD",
    OPTIONS: "OPTIONS",
    CONNECT: "CONNECT",
    TRACE: "TRACE",
};

class Router {
    constructor() {
        this.routes = {}
    }

    #addRoute(method, path, handler) {
        if (typeof path !== "string" || typeof handler !== "function") {
            throw new Error("Invalid argument types: path must be a string and handler must be a function");
        }

        this.routes.set(`${method} ${path}`, handler);
    }

    get(path, handler) {
        this.#addRoute(HTTP_METHODS.GET, path, handler);
    }
    post(path, handler) {
        this.#addRoute(HTTP_METHODS.POST, path, handler);
    }
    put(path, handler) {
        this.#addRoute(HTTP_METHODS.PUT, path, handler);
    }

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

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

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

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

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

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

    ...
}
```

Let's go through the new additions in our code:

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

post(path, handler) {
    this.#addRoute(HTTP_METHODS.POST, path, handler);
}
/** rest HTTP method handlers **/
```

We've created new utility methods on the `Router` class. Each one of these methods call the `addRoute` method by passing in required parameters. You'd notice that we've also made the `addRoute` method private. Since we wish to use it internally in our library and not expose it, it's a good practice to hide it from any external use.

```js
const HTTP_METHODS = { ... }
```

We've created an object of all the HTTP methods, so that we can use their names with the `HTTP_METHODS` namespace, instead of directly passing in strings as an argument, for example:

```js
this.#addRoute("GET", path, handler);
```

There's nothing wrong with this approach too, but I prefer to avoid raw strings. `"GET"` can mean many things, but `HTTP_METHODS.GET` gives us the actual idea of what it is all about.

Let's update our testing code to call the newly created http methods instead:

```js
// file: index.js

...

router.get("/", function handleGetBasePath(req, res) {
    console.log("Hello from GET /");
    res.end();
});

router.post("/", function handlePostBasePath(req, res) {
    console.log("Hello from POST /");
    res.end()
});

...
```

If we do a quick test on both the endpoints, every thing seems to be working alright:

```bash
$ curl -X POST http://localhost:5255/ -v
# Success

$ curl -X POST http://localhost:5255/foo -v
# Not found

$ curl -X POST http://localhost:5255/foo/bar -v
# Not found

$ curl http://localhost:5255/ -v
# Success

$ curl http://localhost:5255/foo -v
# Not found

$ curl http://localhost:5255/foo -v
# Not found
```

Great! This looks much better than the previous implementation.

[![Read Next](/assets/imgs/next.png)](/chapters/ch06.04-the-need-for-a-trie.md)
