1
votes

I'm learning Go and came across the gorilla/mux router. I wanted to have dynamic routes in a text file such as:

/user/1

/post/1

I wrote the following code for this purpose :

func (s *Server) RegRoutes(routes []Route) {
    for _, r := range routes {
        func(route Route) {
            s.Router.HandleFunc(route.Path, func(w http.ResponseWriter, r *http.Request) {    
                w.Header().Add("Content-Type", "application/json")
                s.sendJson(w, route) // send response to client
            }).Methods(route.Method)
        }(r)
    }
}

and everything is working fine. But I want to edit the text file and add some more fields or edit the existing ones without rebuild the project or restart the server. I found this but I couldn't understand what is it and I don't know how to use it.

Is there anyway to modify the existing routes or add more routes during the run-time?

Edit:

I added this:

s.Router.HandleFunc("/reload", func(w http.ResponseWriter, r *http.Request) {

        s.mu.Lock()
        s.Router = mux.NewRouter()
        s.mu.Unlock()

        // load text file and register new routes here
        ....


        s.Router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
            tpl, err1 := route.GetPathTemplate()
            met, err2 := route.GetMethods()
            fmt.Println(tpl, err1, met, err2)
            return nil
        })
        fmt.Fprintf(w, "RELOAD")
    })

When I print the routes after registering the new routes and replacing the Router, they are registered but when I browse the route in browser it gives me 404 error.

1

1 Answers

0
votes

If I understand what you are trying to achieve, it will look something like this:

package main

import (
    "fmt"
    "github.com/gorilla/mux"
    "net/http"
)

var router = mux.NewRouter()
func handler(w http.ResponseWriter, r *http.Request) {
    w.Write([]byte("bla"))
}

func reloadHandler(w http.ResponseWriter, r *http.Request) {
    router.Walk(func(route *mux.Route, router *mux.Router, ancestors []*mux.Route) error {
        t, err := route.GetPathTemplate()
        if err != nil {
            return err
        }
        fmt.Println(t)
        if t == "/" {
            route.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
                writer.Write([]byte("akjbsdkabdjkbaksdj"))
            })
        }
        return nil
    })
}

func main() {

    router.HandleFunc("/", handler)
    router.HandleFunc("/reload", reloadHandler)

    http.ListenAndServe("localhost:8080", router)
}

The router declaration goes outside main function and it can be accessed by the reload handler to add another route.

and the path walk you can check if it is the path you want to change, and then change it.