My directory structure looks like this:
myapp/
|
+-- moduleX
| |
| +-- views.go
|
+-- start.go
The app gets started with start.go
and from there I configure all the routes and import the handlers from moduleX/views.go
like this:
package main
import (
"net/http"
"github.com/gorilla/mux"
"myapp/moduleX"
)
func main() {
r := mux.NewRouter()
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
r.HandleFunc("/", moduleX.SomePostHandler).Methods("POST")
r.HandleFunc("/", moduleX.SomeHandler)
http.Handle("/", r)
http.ListenAndServe(":8080", nil)
}
Now I want to add more modules and ask myself if (and how) it is possible to define the urls in the module in a urls.go
file and somehow "import" them in start.go
. Specifically I want start.go
to know all the URLs in all the somemodule/urls.go
files with just one import or some kind of a module.GetURLs
function.
Package gorilla/mux implements a request router and dispatcher for matching incoming requests to their respective handler. The name mux stands for "HTTP request multiplexer". Like the standard http.
Using Gorilla Mux and the HTTP module in GoLang, we can serve static files directly from the file system. http. FileServer is the Handler that we can use to serve static files to the user. FileServer returns a handler that serves HTTP requests with the contents of the file system rooted at the root.
Gorilla Mux provides functionalities for matching routes, serving static files, building single-page applications (SPAs), middleware, handling CORS requests, and testing handlers. This tutorial will walk you through using the Gorilla Mux package as a router for your applications.
The name mux stands for "HTTP request multiplexer". Like the standard http. ServeMux, mux. Router matches incoming requests against a list of registered routes and calls a handler for the route that matches the URL or other conditions.
Why not get the handlers to insert themselves into the routes table?
If you're defining each handler in its own go file, use the `init()` func for each file to add the handler to a global routing table
So something like:
main.go:
type route{
method string
path string
handler func(w http.ResponseWriter, r *http.Request)
}
var routes = make([]route,0)
func registerRoute(r route){
routes = append(routes,r)
}
func server(){
r := mux.NewRouter()
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./templates/static/"))))
// set up all the registered routes
for _, rt = range(routes){
r.HandleFunc(rt.path,rt.handler).Methods(rt.Method)
}
// and there's usually some other stuff that needs to go in here
//before we finally serve the content here!
http.ListenAndServe(":8080", nil)
}
yourmodule.go:
func init(){
r = route{
method="GET",
path="/yourmodule/path/whatever",
handler=yourHandlerFunc,
}
registerRoute(r)
}
func yourHandlerFunc(w http.ResponseWriter, r *http.Request){
//awesome web stuff goes here
}
init() gets called for each file in a package before execution of the package main() so you can be sure that all your handlers will be registered before you kick the server off.
This pattern can be extended to allow for more tricksy registration gubbins to happen as needed, since the modules themselves are now in charge of their own registration, instead of trying to cram all the special cases into one registration func
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With