I am new to Golang, I am testing the net/http to run some path but I got some problem that I don't understand.
Here is my codes.
package main
import (
"fmt"
"net/http"
)
type Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
fmt.Println("404");
return
}
fmt.Println("index content ", Content)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
Content.Data = data
fmt.Println("test content ", Content)
}
So, if I go to index http://localhost:8080/
, I got empty content index content {{false } map[]}
,
And I goto http://localhost:8080/test
I got the content correctly , test content {{false } map[data1:data 1 content data2:data 2 content]}
,
But when I go back to index http://localhost:8080/
there already content there index content {{false } map[data1:data 1 content data2:data 2 content]}
,
So question here, why am I not getting the empty struct content when I back to the index? I thought the struct will be in initial state with every single request? The http should be stateless, right?
What you are probably experiencing is the result of this code or something similar (your code does not compile):
package main
import (
"fmt"
"net/http"
)
var Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", Content)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
Content.Data = data
fmt.Println("test content ", Content)
}
With this you are creating a global variable Content
that keeps its state across calls to the webserver. What you probably intended is this:
package main
import (
"fmt"
"net/http"
)
type Content struct {
Data map[interface{}]interface{}
}
func main() {
mux := http.NewServeMux()
mux.Handle("/favicon.ico", http.NotFoundHandler())
mux.HandleFunc("/", Index)
mux.HandleFunc("/test", Testhandler)
http.ListenAndServe(":8080", mux)
}
func Index(w http.ResponseWriter, r *http.Request) {
var c Content
if r.URL.Path != "/" {
fmt.Println("404")
return
}
fmt.Println("index content ", c)
}
func Testhandler(w http.ResponseWriter, r *http.Request) {
var c Content
data := make(map[interface{}]interface{})
data["data1"] = "data 1 content"
data["data2"] = "data 2 content"
c.Data = data
fmt.Println("test content ", c)
}
Content
a type as you already did in your sample (that way it is not a global variable any more but defining a type we can reuse)Content
in each call where it is needed (not globally as we do not want it to keep its content across server calls)You cannot use a type without declaring a variable from it first. That is why your sample did not build. If you try go will complain that Content
is not an expression.