Reputation: 3213
I reach a situation that inside a Go Gin Handler, I need to call another handler.
I figured that composing a new gin.Context object is hard, so it maybe easier just make a request to localhost, which going through the router although it is not necessary.
So is there a more efficient method that I can call directly another handler?
However it comes to that how to get the running URL ? Of course it can be hard coded since it is known, but is there a function like below?
ts := httptest.NewServer(GetMainEngine())
defer ts.Close()
log.Println(GetJWTMiddleware())
// here ts.URL is the running url in test
req, _ := http.NewRequest("POST", ts.URL + "/u/login", bytes.NewBuffer(loginPostString))
How to get the ts.URL
with just gin?
Upvotes: 1
Views: 1625
Reputation: 79754
The best way to call another handler is not to. Instead, abstract the common logic to a new function, and call that. Example:
func handler1(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path()
row := r.URL.Query().Get("rowid")
/* ... do something here with path and row ... */
w.Write(someResponse)
}
func handler2(w http.ResponseWriter, r *http.Request) {
path := "/some/hard-coded/default"
/* ... call handler1 ... */
}
Change this to:
func handler1(w http.ResponseWriter, r *http.Request) {
path := r.URL.Path()
row := r.URL.Query().Get("rowid")
someResponse, err := common(path, row)
w.Write(someResponse)
}
func handler2(w http.ResponseWriter, r *http.Request) {
path := "/some/hard-coded/default"
row := r.URL.Query().Get("someRowID")
result, err := common(path, row)
w.Write(result)
}
func common(path, row string) (interface{}, error) {
/* ... do something here with path and row ... */
}
As a general rule, the only thing calling your handler functions should be your mux/router, and your unit tests.
Upvotes: 3