Chi: It is unclear how to obtain POST form values.

Created on 16 Aug 2018  路  4Comments  路  Source: go-chi/chi

I'm trying to process form data that is POSTed and must be doing something wrong. The form template has this input tag:

My router rules specify a POST operation like this:

router := chi.NewRouter()
router.Post("/search", search.GeneralSearch)

The route handler code then tries to obtain the POST data like this:

func GeneralSearch(w http.ResponseWriter, r *http.Request) {
    query := r.Context().Value("query").(string)
    if query == "" {
        glog.Error("Search query not found!")
        return
    }
}

I can see in the debugger that the post is properly calling GeneralSearch() but I cannot see the form data in any variable or struct that exists in the context of the function. Clearly I'm doing something wrong but don't know what. The REST example is not much help because it seems to hide the form data fetching behind the use of the chi Render middleware but because I'm using a different Render middleware I can't just mimic the example.

Most helpful comment

I knew that I should not be trying to add my own content into contexts because that data should be request-specific. Somewhere I had thought that I got a hint that form data would be in the context. Clearly I was wrong.

Perhaps the documentation of how to use he Render middleware is unclear then because I found it very confusing. It seems much simpler to just use the http.Request methods. I could not determine, from docs, precisely what the deserializing and binding would create for a struct. Without knowing that detail the struct that is created is not very useful.

All 4 comments

I figured it out and as a result will suggest a revision to examples that show a POST operation. The code in the REST example is unclear and is more complex than necessary. Here's the code snippet that works:

func GeneralSearch(w http.ResponseWriter, r *http.Request) {
    r.ParseForm()
    query := r.Form.Get("query")
    if query == "" {
        glog.Error("Search query not found!")
        return
    }
}

Contexts are generally used to carry custom data among handlers. No form or query data should be carried on top of contexts in root handlers, likewise it's not documented anywhere so.

Besides, if you will not inspect the form data, you can take advantage of FormValue or PostFormValue where ParseForm is run if necessary.

Render middleware just smooths the way by deserializing and binding the data into structs. It uses the same thing under the hood.

I knew that I should not be trying to add my own content into contexts because that data should be request-specific. Somewhere I had thought that I got a hint that form data would be in the context. Clearly I was wrong.

Perhaps the documentation of how to use he Render middleware is unclear then because I found it very confusing. It seems much simpler to just use the http.Request methods. I could not determine, from docs, precisely what the deserializing and binding would create for a struct. Without knowing that detail the struct that is created is not very useful.

It would be a good idea to have this in the main readme

Was this page helpful?
0 / 5 - 0 ratings

Related issues

makhov picture makhov  路  4Comments

netsharec picture netsharec  路  6Comments

valsor picture valsor  路  5Comments

rickb777 picture rickb777  路  12Comments

kevinconway picture kevinconway  路  8Comments