-
-
Save andreagrandi/97263aaf7f9344d3ffe6 to your computer and use it in GitHub Desktop.
package main | |
import ( | |
"encoding/json" | |
"fmt" | |
"net/http" | |
) | |
type test_struct struct { | |
Test string | |
} | |
func parseGhPost(rw http.ResponseWriter, request *http.Request) { | |
decoder := json.NewDecoder(request.Body) | |
var t test_struct | |
err := decoder.Decode(&t) | |
if err != nil { | |
panic(err) | |
} | |
fmt.Println(t.Test) | |
} | |
func main() { | |
http.HandleFunc("/", parseGhPost) | |
http.ListenAndServe(":8080", nil) | |
} |
thank you
Don't you need to close the request.Body
?
Nevermind. I read in the docs that
The Server will close the request body. The ServeHTTP Handler does not need to.
Thanks for posting the example.
invalid character 't' looking for beginning of object key string
try curl -X POST -d "{\"test\": \"that\"}" http://localhost:8080
curl -X POST -d '{"test": "that"}' http://localhost:8080
I get an empty response when running this:
`$ curl -X POST -d "{"test":"something"}" http://localhost:8080
$ `
`$ ./parse_json_post
`
EDIT: Apparently the keyname does matter, but it's not intuitive (for me at least) that the struct member is capitalized and the json key name is not.
How would you tackle parsing different kinds of request. I am struggling passing in a struct to the function.
Don't forget
defer r.Body.Close()
Example
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"time"
"github.com/gorilla/mux"
)
type player struct {
Name string
Club string
Age uint8
}
func mainLogic(w http.ResponseWriter, r *http.Request) {
if r.Method == "POST" {
var tempPlayer player
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&tempPlayer)
if err != nil {
panic(err)
}
defer r.Body.Close()
fmt.Printf("Got %s age %d club %s\n", tempPlayer.Name, tempPlayer.Age, tempPlayer.Club)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(tempPlayer)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Method not allowed."))
}
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", mainLogic).Methods("POST")
srv := &http.Server{
Handler: r,
Addr: "localhost:8000",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
Go JSON content-type using the middleware
package main
import (
"encoding/json"
"fmt"
"log"
"net/http"
"time"
"github.com/gorilla/mux"
)
type player struct {
Name string
Club string
Age uint8
}
func middleware(handler http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
fmt.Println("Executing Content-type middleware before the request phase!")
if r.Header.Get("Content-type") != "application/json" {
w.WriteHeader(http.StatusUnsupportedMediaType)
w.Write([]byte("415 - Unsupported Media Type. Only JSON files are allowed"))
return
}
// Pass control back to the handler
handler.ServeHTTP(w, r)
})
}
func mainLogic(w http.ResponseWriter, r *http.Request) {
// Business logic here
if r.Method == "POST" {
fmt.Println("INSIDE LOGIC")
var tempPlayer player
decoder := json.NewDecoder(r.Body)
err := decoder.Decode(&tempPlayer)
if err != nil {
panic(err)
}
defer r.Body.Close()
fmt.Printf("Got %s age %d club %s\n", tempPlayer.Name, tempPlayer.Age, tempPlayer.Club)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(tempPlayer)
} else {
w.WriteHeader(http.StatusMethodNotAllowed)
w.Write([]byte("Method not allowed."))
}
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", mainLogic).Methods("POST")
r.Use(middleware)
srv := &http.Server{
Handler: r,
Addr: "localhost:8000",
WriteTimeout: 15 * time.Second,
ReadTimeout: 15 * time.Second,
}
log.Fatal(srv.ListenAndServe())
}
A simple middleware function to check if the POST request is in JSON format.
invalid character 't' looking for beginning of object key string
I fixed it by replacing first and last double quotes to single quotes: -d "{"test": "that"}" -> -d '{"test": "that"}'
Thank you. It helped me to resolved issue.
Test it with: curl -X POST -d "{"test": "that"}" http://localhost:8080