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!
Top comments (0)