Search code examples
goclosuresservemux

ServeMux gets evaluated only once


I am seeing some unexpected behavior in my Go program and am hoping somebody can explain it to me. I have the following basic program:

    package main

import (
    "fmt"
    "log"
    "net/http"
)

func main() {
    runserver()
}

func runserver() {
    err := http.ListenAndServe(":5000", mux())
    if err != nil {
        log.Fatal(err)
    }
}

func mux() *http.ServeMux {
    mux := http.NewServeMux()

    mux.HandleFunc("/p1", func1)
    mux.HandleFunc("/p2", func2)
    mux.HandleFunc("/p3", midd("hello", func3))

    return mux
}

func func1(w http.ResponseWriter, r *http.Request) {
    fmt.Println("called 1")
    w.Write([]byte("hello from 1"))
}

func func2(w http.ResponseWriter, r *http.Request) {
    fmt.Println("called 2")
    w.Write([]byte("hello from 2"))
}

func func3(w http.ResponseWriter, r *http.Request) {
    fmt.Println("called 3") 
    w.Write([]byte("hello from 3"))
}

func midd(random string, hfunc http.HandlerFunc) http.HandlerFunc {
    fmt.Println(random)

    return hfunc
}

When I run the program, I immediately see hello (from func midd) printed in the terminal. When I navigate to localhost:5000/p1, it prints "called 1", if I navigate to /p2 it prints "called 2" but when I navigate to /p3, I get "called 3" in the terminal but not hello.

Can anybody explain to my why midd() is called when the program starts but not when I navigate to "/p3"?


Solution

  • The statement mux.HandleFunc("/p3", midd("hello", func3)) executes the midd("hello", func3) call expression "then and there" and passes its result to the mux.HandleFunc function call. This result that's passed to HandleFunc is then invoked for each incoming /p3 request.

    And the aforementioned statement is executed only once because mux() is called by runserver() only once, and runserver() is called by main() only once, and main() is executed only once.