Question: Je suis actuellement imprimer ma réponse dans le func Index
comme cela fmt.Fprintf(w, string(response))
cependant, comment puis - je envoyer JSON correctement dans la demande de sorte qu'il peut être consommé par une vue?
package main
import (
"fmt"
"github.com/julienschmidt/httprouter"
"net/http"
"log"
"encoding/json"
)
type Payload struct {
Stuff Data
}
type Data struct {
Fruit Fruits
Veggies Vegetables
}
type Fruits map[string]int
type Vegetables map[string]int
func Index(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
response, err := getJsonResponse();
if err != nil {
panic(err)
}
fmt.Fprintf(w, string(response))
}
func main() {
router := httprouter.New()
router.GET("/", Index)
log.Fatal(http.ListenAndServe(":8080", router))
}
func getJsonResponse()([]byte, error) {
fruits := make(map[string]int)
fruits["Apples"] = 25
fruits["Oranges"] = 10
vegetables := make(map[string]int)
vegetables["Carrats"] = 10
vegetables["Beets"] = 0
d := Data{fruits, vegetables}
p := Payload{d}
return json.MarshalIndent(p, "", " ")
}
Réponses:
Vous pouvez définir votre en-tête de type de contenu pour que les clients sachent s'attendre à json
w.Header().Set("Content-Type", "application/json")
Une autre façon de marshaler une structure en json consiste à créer un encodeur en utilisant le
http.ResponseWriter
// get a payload p := Payload{d} json.NewEncoder(w).Encode(p)
la source
w.Header().Set("Content-Type", "application/json")
soit correct pour définir le type de contenu, ce n'est pas le cas lors de l'utilisation à lajson.NewEncoder
place, j'obtiens un résultat txt / plain. Est-ce que quelqu'un d'autre comprend cela. La réponse de @poorva a fonctionné comme prévuw.WriteHeader(http.StatusOk)
j'obtiens le résultat ci-dessus.w.WriteHeader(http.StatusOk)
alors j'obtienstext/plain; charset=utf-8
, si je ne règle pas explicitement le code d'état, j'obtiensapplicaton/json
et la réponse a toujours un code d'état 200.Changing the header map after a call to WriteHeader (or Write) has no effect unless the modified headers are trailers.
w.Header().Set("Content-Type", "application/json")
ci-dessusjson.NewEncoder(w).Encode(p)
pour moiD'autres utilisateurs commentent que le
Content-Type
estplain/text
lors de l'encodage. Vous devez définir leContent-Type
premierw.Header().Set
, puis le code de réponse HTTPw.WriteHeader
.Si vous appelez en
w.WriteHeader
premier, puis appelezw.Header().Set
après vous obtiendrezplain/text
.Un exemple de gestionnaire pourrait ressembler à ceci;
func SomeHandler(w http.ResponseWriter, r *http.Request) { data := SomeStruct{} w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusCreated) json.NewEncoder(w).Encode(data) }
la source
Vous pouvez faire quelque chose comme ça dans votre
getJsonResponse
fonction -jData, err := json.Marshal(Data) if err != nil { // handle error } w.Header().Set("Content-Type", "application/json") w.Write(jData)
la source
jData
, peut-être inutilement.Data
peut être de taille arbitraire, en fonction des données rassemblées, donc cela pourrait être un gaspillage de mémoire non trivial. Après le rassemblement, nous copions de la mémoire vers leResponseWriter
flux. La réponse qui utilise json.NewEncoder () etc. écrirait le JSON marshallé directement dans leResponseWriter
(dans son flux ..)Encoder.Encode()
fonctionDans le framework gobuffalo.io, je l'ai fait fonctionner comme ceci:
// say we are in some resource Show action // some code is omitted user := &models.User{} if c.Request().Header.Get("Content-type") == "application/json" { return c.Render(200, r.JSON(user)) } else { // Make user available inside the html template c.Set("user", user) return c.Render(200, r.HTML("users/show.html")) }
puis quand je veux obtenir une réponse JSON pour cette ressource, je dois définir "Content-type" sur "application / json" et cela fonctionne.
Je pense que Rails a un moyen plus pratique de gérer plusieurs types de réponses, je n'ai pas vu la même chose dans gobuffalo jusqu'à présent.
la source
Vous pouvez utiliser ce rendu de package , j'ai écrit pour résoudre ce genre de problème, c'est un wrapper pour servir JSON, JSONP, XML, HTML etc.
la source