I'm not sure why the data being posted is not present when running the following curl request:
curl --request POST http://localhost:4000 --header "Content-Type: application/json" --data '{ "hostname": "bbc.co.uk" }'
against the code below. It's essentially just posting json with the variable hostname
but for some reason it's not appearing in req.Body
or appearing in the Domain
structure array. Please note this is based on this tutorial
package main
import (
"encoding/json"
"log"
"net/http"
"fmt"
"github.com/gorilla/mux"
"github.com/gorilla/handlers"
)
type Domain struct {
hostname string `json:"hostname,omitempty"`
}
var domains []Domain
func CreateDomainEndpoint(w http.ResponseWriter, req *http.Request) {
var domain Domain
fmt.Println(req.Body)
_ = json.NewDecoder(req.Body).Decode(&domain)
domains = append(domains, domain)
json.NewEncoder(w).Encode(domains)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/", CreateDomainEndpoint).Methods("POST")
log.Fatal(http.ListenAndServe(":4000", handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), handlers.AllowedOrigins([]string{"*"}))(router)))
}
hostname
field because the field is not exported. Fix by capitalizing the name of the field.domains
. Fix by protecting access to the variable with a mutex. Here's the code with fixes:
package main
import (
"encoding/json"
"log"
"net/http"
"sync"
"github.com/gorilla/handlers"
"github.com/gorilla/mux"
)
type Domain struct {
Hostname string `json:"hostname,omitempty"`
}
var (
domains []Domain
mu sync.Mutex
)
func CreateDomainEndpoint(w http.ResponseWriter, req *http.Request) {
var domain Domain
if err := json.NewDecoder(req.Body).Decode(&domain); err != nil {
http.Error(w, "bad request", 400)
return
}
mu.Lock()
domains = append(domains, domain)
// To avoid holding the mutex while writing to the
// response body, make a local copy of the slice header.
d := domains
mu.Unlock()
json.NewEncoder(w).Encode(d)
}
func main() {
router := mux.NewRouter()
router.HandleFunc("/", CreateDomainEndpoint).Methods("POST")
log.Fatal(http.ListenAndServe(":4000", handlers.CORS(handlers.AllowedHeaders([]string{"X-Requested-With", "Content-Type", "Authorization"}), handlers.AllowedMethods([]string{"GET", "POST", "PUT", "HEAD", "OPTIONS"}), handlers.AllowedOrigins([]string{"*"}))(router)))
}