how to build own simple router in golang?

go, httpserver, router

Solution

Your main function, by using the `:=` notation, is declaring and initialising a new local variable called r, whose scope is different from the global variable you have on the top of your listing.

This means that the `r` variable that you're adding the handler to, is not the global one that you're trying to assign to the `Http.Server` struct, therefore your `ServeHTTP` will not find any mapping at all into its own receiver `r`.

A solution is to declare the `r Router` as a pointer to a `Router`, like this:

var r *Router

and in your handler, you can pass directly the pointer without any dereference:

Session = &http.Server{
        Addr:           port,
        Handler:        r,
        ReadTimeout:    10 * time.Second,
        WriteTimeout:   10 * time.Second,
        MaxHeaderBytes: 1 << 20,
    }

Of course, remember to initialise the variable by assigning the pointer value and not declaring a new local one:

func main() {
    r = newRouter()
    r.Add("/hello", hello)
    Run(":8080")
}

Problem

I am building own router in golang to understand logic , however I am getting 404 error not found normally, i able to running to server but I wrote function in hello name, it is not running. what could reason for this ? ``` package main import ( "fmt" "log" "net/http" "strings" "time" ) var Session *http.Server var r Router func Run(port string) { Session = &http.Server{ Addr: port, Handler: &r, ReadTimeout: 10 * time.Second, WriteTimeout: 10 * time.Second, MaxHeaderBytes: 1 << 20, } log.Fatal(Session.ListenAndServe()) } type Handle func(http.ResponseWriter, *http.Request) type Router struct { mux map[string]Handle } func newRouter() *Router { return &Router{ mux: make(map[string]Handle), } } func (r *Router) Add(path string, handle Handle) { r.mux[path] = handle } func GetHeader(url string) string { sl := strings.Split(url, "/") return fmt.Sprintf("/%s", sl[1]) } func (rt *Router) ServeHTTP(w http.ResponseWriter, r *http.Request) { head := GetHeader(r.URL.Path) h, ok := rt.mux[head] if ok { h(w, r) return } http.NotFound(w, r) } func hello(w http.ResponseWriter, r *http.Request) { fmt.Fprintf(w, "%s", "hello world") } func main() { r := newRouter() r.Add("/hello", hello) Run(":8080") } ```

Original source