Help needed with subrouting in Go

Help needed with subrouting in Go

Hello 👋

I’ve started learning Go a couple days ago. Currently, I’m building Rest APIs using net/http package.

I have figured out most of the basic stuff, but struggling a bit with subrouting. When I add a subrouter using like this

var mux1 = http.NewServeMux()
mux1.HandleFunc()

var mux2 = http.NewServeMux()
mux2.HandleFunc()
mux1.Handle(“/”, middleware.IsAuthenticated(mux2))

I’m trying to add a protected set of routes to a router using a middleware. But, the routes defined in the subrouter are not accessible without adding a trailing slash in the URL when making the request. eg:

My Code

// cmd/main/main.go
package main

import (
“fmt”
“net/http”

“rest-api/internal/middleware”
“rest-api/internal/routes”
“rest-api/internal/utils”
)

func main() {
var middlewareStack = utils.CreateStack(middleware.LogRequest)

var v1Router = http.NewServeMux()
v1Router.Handle(“/v1/”, http.StripPrefix(“/v1”, routes.EchoRouter()))

var usersRouter = routes.UsersRouter()
v1Router.Handle(“/users/”, http.StripPrefix(“/users”, usersRouter))

var server = &http.Server{
Addr: “:8080”,
Handler: middlewareStack(v1Router),
}

fmt.Println(“starting server on port 8080”)
server.ListenAndServe()
}

// internal/routes/users.go
package routes

import (
“encoding/json”
“net/http”

“rest-api/internal/middleware”
)

type User struct {
Name string
Email string
}

func UsersRouter() http.Handler {
var usersMux = http.NewServeMux()
usersMux.HandleFunc(“GET /”, getUsers)

var protectedMux = http.NewServeMux()
protectedMux.HandleFunc(“POST /”, createUser)
usersMux.Handle(“/”, middleware.IsAuthenticated(protectedMux))

return usersMux
}

func getUsers(res http.ResponseWriter, _ *http.Request) {
res.Write([]byte(“users list”))
}

func createUser(res http.ResponseWriter, req *http.Request) {
var newUser User
var err = json.NewDecoder(req.Body).Decode(&newUser)

if err != nil {
res.WriteHeader(http.StatusBadRequest)
res.Write([]byte(err.Error()))
return
}
res.WriteHeader(http.StatusCreated)
res.Write([]byte(“new user created, name: “ + newUser.Name + “, email: “ + newUser.Email))
}

PS

I can achieve the desired behaviour by using the /users prefix in the users.go file instead of the main.go file, but I was wondering if it can be done this way too 🤔

Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *