Search code examples
httpgorequestmicroservices

How to add values to request and redirect in golang


I have API gateway and User service micro services. When a request comes to API gateway, I need to add some values before Rediret() it to user service.

func main(){
    http.HandleFunc("/login", userLogin)

}
func userLogin(res http.ResponseWriter, req *http.Request) {

    uuid := generateUUID()

    // How to add UID to request?
    http.Redirect(res, req, userservice, http.StatusSeeOther)

}

For that I have used method described here.

form,_ := url.ParseQuery(req.URL.RawQuery)
form.Add("uid", "far")
req.URL.RawQuery = form.Encode()

This just go and stop at User Service's login route.

I also tried to use : req.Form.Set("uid","foo")

This gives a panic.

http: panic serving 127.0.0.1:55076: assignment to entry in nil map

My User service :

func main(){
    http.HandleFunc("/login", UserLogin)
}

func UserLogin(res http.ResponseWriter, req *http.Request) {
     req.ParseForm()
     requestID := req.FormValue("uid")
     userID := req.FormValue("userid")

     if userID =="sachith"{
        sendRequest(requestID)
        http.Redirect(res, req, "http://localhost:7070/home", http.StatusSeeOther)
    }

Is there a way to add values to request we receive for a route and the redirect it to another service?


Solution

  • To add query parameters to a redirect location you simply add them to the url argument of the Redirect function.

    Also, you should not modify the *http.Request argument that's passed in to Redirect to specify the target location, that's not what it's for. 1st, modifying it would only have an effect on relative redirects, which is not what you're trying to do here. 2nd, the url is designated for that purpose and can be used consistently to do both relative and absolute redirects. There's no advantage going against the design here.

    apigateway/main.go

    package main
    
    import (
        "net/http"
    )
    
    func main() {
        http.HandleFunc("/login", loginHandler)
        http.ListenAndServe(":8080", nil)
    }
    
    func loginHandler(w http.ResponseWriter, r *http.Request) {
        uuid := "911cf95b-6b3f-43fd-b695-c80c79145c51" // generate uuid
        http.Redirect(w, r, "http://localhost:8081/login?user_id="+uuid, http.StatusSeeOther)
    }
    

    userservice/main.go

    package main
    
    import (
        "net/http"
    )
    
    func main() {
        http.HandleFunc("/login", loginHandler)
        http.ListenAndServe(":8081", nil)
    }
    
    func loginHandler(w http.ResponseWriter, r *http.Request) {
        uuid := r.URL.Query().Get("user_id")
        w.Write([]byte(uuid))
    }