web-dev-qa-db-ja.com

Goを使用してJSON応答を提供する方法は?

質問:現在、私の応答をfunc Indexのように印刷していますfmt.Fprintf(w, string(response))ただし、リクエストでJSONを適切に送信して、ビューによって消費されますか?

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, "", "  ")
}
63
Matthew Harwood

クライアントがjsonを期待するようにコンテンツタイプヘッダーを設定できます

w.Header().Set("Content-Type", "application/json")

構造体をjsonにマーシャリングする別の方法は、http.ResponseWriterを使用してエンコーダーを構築することです

// get a payload p := Payload{d}
json.NewEncoder(w).Encode(p)
97
dm03514

エンコード時にContent-Typeplain/textであるとコメントする他のユーザー。 Content-Type最初にw.Header().Setを設定し、次にHTTP応答コードw.WriteHeaderを設定する必要があります。

w.WriteHeaderを最初に呼び出す場合は、plain/textを取得した後にw.Header().Setを呼び出します。

ハンドラーの例は次のようになります。

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)
}
19
k3mist

getJsonResponse関数でこのようなことができます-

jData, err := json.Marshal(Data)
if err != nil {
    // handle error
}
w.Header().Set("Content-Type", "application/json")
w.Write(jData)
16
poorva

Gobuffalo.ioフレームワークでは、次のように動作します。

// 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"))
}

そして、そのリソースのJSON応答を取得したい場合は、「Content-type」を「application/json」に設定する必要があり、それが機能します。

Railsには複数の応答タイプを処理するためのより便利な方法があると思いますが、これまでのところゴバッファローでは同じことがわかりませんでした。

1
Aleks Tkachenko

この パッケージレンダラー を使用できます。この種の問題を解決するために書いたもので、JSON、JSONP、XML、HTMLなどを提供するラッパーです。

0
user3679289