How to organize cartoon gorilla routes?

I use Gorilla Mux to write a REST API and I am having problems organizing my routes, currently all my routes are defined in the main.go file like this

 //main.go package main import ( "NovAPI/routes" "fmt" "github.com/gorilla/mux" "net/http" ) func main() { router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/hello", func(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Hello") }) router.HandleFunc("/user", func(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "User") }) router.HandleFunc("/route2", func(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Route2") }) router.HandleFunc("/route3", func(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Route3") }) // route declarations continue like this http.ListenAndServe(":1128", router) } 

so I want to do this and split this route declaration into several files, how would I do it? early.

+6
source share
2 answers

How about this?

 //main.go package main import ( "NovAPI/routes" "fmt" "github.com/gorilla/mux" "net/http" ) func main() { router := mux.NewRouter().StrictSlash(true) router.HandleFunc("/hello", HelloHandler) router.HandleFunc("/user", UserHandler) router.HandleFunc("/route2", Route2Handler) router.HandleFunc("/route3", Route3Handler) // route declarations continue like this http.ListenAndServe(":1128", router) } func HelloHandler(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Hello") } func UserHandler(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "User") } func Route2Handler(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Route2") } func Route3Handler(res http.ResponseWriter, req *http.Request) { fmt.Fprintln(res, "Route3") } 

This way you can put your handlers in other files or even other packages.

If you get additional dependencies, such as a database, you can even avoid the need to use the global var with the constructor trick:

 //main.go func main() { db := sql.Open(…) //... router.HandleFunc("/hello", NewHelloHandler(db)) //... } func NewHelloHandler(db *sql.DB) func(http.ResponseWriter, *http.Request) { return func(res http.ResponseWriter, req *http.Request) { // db is in the local scope, and you can even inject it to test your // handler fmt.Fprintln(res, "Hello") } } 
+5
source

I like checking out other projects on github to get ideas on how to do things, and for these cases, I usually look at the Docker repo first . So they do it:

For system routes, define all handlers in system_routes.go , and then initialize these routes with the NewRouter function in system.go .

 type systemRouter struct { backend Backend routes []router.Route } func NewRouter(b Backend) router.Router { r := &systemRouter{ backend: b, } r.routes = []router.Route{ local.NewOptionsRoute("/", optionsHandler), local.NewGetRoute("/_ping", pingHandler), local.NewGetRoute("/events", r.getEvents), local.NewGetRoute("/info", r.getInfo), local.NewGetRoute("/version", r.getVersion), local.NewPostRoute("/auth", r.postAuth), } return r } // Routes return all the API routes dedicated to the docker system. func (s *systemRouter) Routes() []router.Route { return s.routes } 

Note that systemRouter implements the router.Router interface, and the Routes function returns [] router.Route, and their handlers are defined as

 func(ctx context.Context, w http.ResponseWriter, r *http.Request, vars map[string]string) error 

instead of the standard HTTP Go handler:

 func(w http.ResponseWriter, r *http.Request) 

So, there is additional code to convert the Docker API handler to an HTTP traffic handler in makeHttpHandler .

And finally, to add these routes to their multiplexer, on server.go they implement several other functions to add middleware to their handlers.

If this is what you think is what you are looking for, then take the time to analyze the Docker code for your routes, and if you need me to develop more or miss something, post a comment.

+1
source

All Articles