Lesson Description

The "Chi Router" Lesson is part of the full, Complete Go for Professional Developers course featured in this preview video. Here's what you'd learn in this lesson:

Melkey installs the Chi package, which provides methods for adding middleware and routes to the application. The HealthCheck handler function is refactored, adding a method receiver, so it's now part of the Application struct. A SetupRoutes function is added in the routes module to instantiate the Chi router and define the "/health" route.

Preview
Close

Transcript from the "Chi Router" Lesson

[00:00:00]
>> Melkey: So like I said, main file is supposed to be kind of tight, clean. Ours is getting there, especially with the flag ports getting nicer. But this is just an eyesore. This HealthCheck, it's an eyesore. Why is this there, right? Does this mean every time we add a new handle function, it has to be appended here?

[00:00:18]
That would be sickening. So what I'm going to do is I'm gonna just copy this. I'm gonna go to our app.go file right here. I'm gonna paste it into its own separate function, okay? My editor hates me, so I have to bring in all those packages, so net/http, and then format, okay?

[00:00:42]
But the next thing I wanna do is I wanna make this exist on our app struct, and this is slowly going to present how we're gonna structure the rest of our app. So here I'm gonna make a method receiver on a Application, like so, all right? And just as a final reminder, this means that our application struct has now a method called HealthCheck.

[00:01:05]
But if I just did that, what's going on in main.go? We have this. If I remove this, now, we have this error, right, undefined HealthCheck. So how do we solve this? Well, there's a few things we can do to solve it. The one I'm gonna introduce is actually introducing our Chi package, so Chi v5.

[00:01:27]
So I'm gonna briefly go here and showcase the first package we're gonna bring into our application. This is Go Chi, all right? So Go Chi is a lightweight, idiomatic and composable router for building Go HTTP services. You can see it has 19.2 thousand GitHub stars. It is decently maintained.

[00:01:51]
Still from three weeks ago, it has some maintenance, even some two weeks ago. It is a very standard package that a lot of engineers choose to use. And you don't have to use Chi, there's a bunch of these. There's Gin, there's Echo, there's Gorilla Mux. It really depends on what you want, right?

[00:02:10]
And we're gonna use Chi to handle our routing, but also Chi gives the ability to create middlewares and use Chi's built-in middleware. So I personally like Chi because it's so close to the standard library. It implements the interfaces for the standard library, much do like the other ones I mentioned as well.

[00:02:31]
But for me, I just thought Chi was just super simple, super light to use. We're gonna implement Chi, we're gonna take it. So the way we do this is we're gonna copy this. I'm gonna write that in my terminal and give you guys a chance to copy it down.

[00:02:44]
But if we go back to the terminal, open up a terminal here. We can just do, go get -u, and then github.com/go-chi/chi/v5. Now, remember when I talked about the Go module publicly facing, this is why. This is how we pull different packages from GitHub, from Go Codeberg, GitLab, I don't know, into our package here.

[00:03:12]
>> Speaker 2: You mentioned with Chi, that it enables us to write middleware. Do you mean it's easier to write middleware with, or what is the?
>> Melkey: Yeah, no, great question. So enables middleware is probably not the best description, we are able to write middleware without Chi. What Chi does is it modifies the request pointer from our methods, from curls that request pointer.

[00:03:36]
And it allows us to inject things and retrieve things from the request, to basically insert our own middleware. And it does that very elegantly, okay? But you can do this without Chi. I just found the way it groups everything, it made sense to me to use it, okay?

[00:03:54]
Let's go ahead and run this. You can see Go added. Now, one thing I wanna point out is we now have a go.sum file, which we didn't have before. For those of us who are in the web dev world, we are probably familiar with package-lock.json. This is the package-lock.json equivalent.

[00:04:15]
This is particular hashes of what we pulled down from Go, from Chi v5. So when our application runs, the go.sum provides the exact hashes for us to replicate that pull into our application. And then if you look, our go.mod now has a new require field for our Chi package, okay, so small modifications here.

[00:04:43]
And with all that, we're gonna go into our route and we're going to set this up. So our routes package is gonna have one really crucial role. It's gonna route everything, okay? And it's gonna have one function. And for me, the way I like to organize my projects, this allows me to just go here, know what to modify.

[00:05:03]
Middlewares go here, new functions defined here. Grouping functions go here, okay? Private functions that a person signed in versus not signed in, will be all defined in here. And the way we're gonna do this is we're gonna create a function, capital SetupRoutes, okay? And SetupRoutes is going to take one argument.

[00:05:23]
It's going to be our application, app.Application. And it's going to return one item, a pointer to chi.Mux, okay? And then Mux just adheres. Again, if you look into Mux real quick, it is basically a struct that computes all the handlers for our function. And this Mux struct has all the fields to satisfy the native standard library HTTP function interface.

[00:06:02]
Meaning we can use now this new Chi Mux, if we go back to our main.go, to replace this HandleFunc, okay? So now if we go back to routes, we can define r as chi.NewRouter, okay? And then here we're gonna do r.Get, cuz we wanna create a new GET method.

[00:06:26]
The path is gonna be /health. And then the function, well, remember our HealthCheck function that used to exist in main.go it's no longer there. We moved it to app.go, but we made it as a method on our Application struct. Which now, if we go back here, we can just simply put app.HealthCheck as a first class citizen.

[00:06:53]
Then we can return r. If we go back to our main.go now, we can import up here internal/routes, okay, import not used. Let's go down here, where we had the previous HealthCheck. Nuke that, we don't want that anymore. What we're going to do is declare r as route.SetupRoutes.

[00:07:18]
I'm gonna pass in our app, like so. Now we've declared unused r, we can put into the property of our HTTP server struct, Handler. And we just pass r, like so. And now in terms of every time we add new methods, we know that all we have to do is add them here.

[00:07:42]
The pipelining is done because of this small handler passing r, that's been fixed for us. And so if we go back, nuke our server, go run main.go, it's going to run. And here, if we just curl localhost:8080/health, it's gonna work the exact same way. But now we are using Chi.

[00:08:05]
Now we have a way to orchestrate all of our routes. And now we have a way to safely and maybe better organize our project for when we include more methods onto the project.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now