Skip to content

JSONレスポンスを返してみよう

先ほど作ったmain.goに、レスポンスとして JSON を返すエンドポイントを追加しましょう。

TIP

JSON について分からない人は JSONってなにもの? | Think IT(シンクイット)

TIP

Go の構造体についてわからない人は↓を見ると良いです。

https://go-tour-jp.appspot.com/moretypes/2

JSON をレスポンスとして返すためには、c.JSONメソッドに構造体を渡します。
先ほどの章で作成したmain.goに、以下のようなエンドポイントを追加して、JSONレスポンスを返してみましょう。

go
package main

import (
	"net/http"

	"github.com/labstack/echo/v4"
)

// JSONで返すための構造体を定義
type jsonData struct {
	Number int
	String string
	Bool   bool
}

func main() {
	// Echoの新しいインスタンスを作成
	e := echo.New()

	// 「/json」というパスのエンドポイントを定義
	e.GET("/json", jsonHandler)

	// Webサーバーをポート番号8080で起動し、エラーが発生した場合はログにエラーメッセージを出力する
	e.Logger.Fatal(e.Start(":8080"))
}

func jsonHandler(c echo.Context) error {
	// レスポンスとして返す値を構造体として定義
	response := jsonData{
		Number: 10,
		String: "hoge",
		Bool:   false,
	}

	// HTTPステータスコードは200番で、構造体をJSONに変換してクライアントに返す
	return c.JSON(http.StatusOK, &response)
}

書き換えたら、localhost:8080/json にアクセスして確認してみましょう。

タグを追加することで構造体のフィールドに対応する、JSON のキー名を指定できます。
Go の構造体のフィールドはパスカルケースですが、JSON のフィールドは普通キャメルケース / スネークケースであるため、main.goの構造体を以下のように書き換えましょう。

go
type jsonData struct {
    // Numner -> number (omitemptyは、ゼロ値の場合はそのフィールドを出力しないという意味)
	Number int    `json:"number,omitempty"`
	String string `json:"string,omitempty"`
	Bool   bool   `json:"bool,omitempty"`
}

参考: encoding/json#Marshal

Postmanでリクエストしてみよう

Postman を起動したら、workspace を作成して移動し、Ctrl + N->HTTPまたはOverviewタブの横にある+を押して、リクエスト設定画面を開きます。

Enter URL or paste textとあるところで HTTP method と URL を指定できます。
Postman を使って、GET リクエストを自分のサーバーに送ってみましょう。 つまり、HTTP MethodとしてGETを使用して、URLhttp://localhost:8080/helloにリクエストを送信しましょう。

HTTP Method: GET

URL: http://localhost:8080/hello

以下の画像のように設定してください。

Hello, World.

と表示されれば成功です。

次に POST リクエストを使ってみましょう

POST ではサーバーにデータを送ることができます。

  1. Postman で Body タブを選択
  2. ラジオボタンのrawを選択
  3. 右に出てくるプルダウンからJSON(application/json)を選択します
    POST で渡せるデータの型は複数あり、上記の操作で JSON を使うということを明示しています。

以下のように自分の traQ ID を POST してみましょう。

HTTP method: POST

URL: https://eo6mn2b7rlihmgg.m.pipedream.net
json
{
    "traq_id": "pikachu"
}

traq_idpikachuの例だと、上の画像のように、以下のような JSON が返ってきます。

{
    ...
    "body": {
        "traq_id": "pikachu"
    }
}

自分のサーバーでPOSTを受け取ってみよう

POST で JSON を受け取って、内容をそのまま返すサーバーを作ってみます。
e.GETと同じように、e.POSTと書くことで POST を受け取ることができます。
POST のハンドラは、受け取りたい JSON を示す空の変数を先に用意し、ContextBindに渡すことで送られてきたデータを取り出すことができます。
データが存在しなかったりした場合には、返り値のerrにエラーが入ります。
逆にエラーがないときはerrnilが返ってくるので、ifで条件分岐をします。

go
package main

import (
	"fmt"
	"net/http"

	"github.com/labstack/echo/v4"
)

// Jsonで受け取り、構造体に変換して返すための構造体を定義
type jsonData struct {
	Number int    `json:"number,omitempty"`
	String string `json:"string,omitempty"`
	Bool   bool   `json:"bool,omitempty"`
}

func main() {
	e := echo.New()

	// `e.GET`と同じように、`e.POST`と書くことで POST を受け取ることができます。
	e.POST("/post", postHandler)

	e.Logger.Fatal(e.Start(":8080"))
}

func postHandler(c echo.Context) error {
	// 受け取りたい JSON を示す空の変数を先に用意する。
	data := &jsonData{}
	// 受け取った JSON を data に代入する
	err := c.Bind(data)

	if err != nil { // エラーが発生した時、以下を実行
		// 正常でないためステータスコード 400 Bad Requestを返し、 エラーを文字列に変換して出力
		return echo.NewHTTPError(http.StatusBadRequest, fmt.Sprintf("%+v", err))
	}
	// エラーが起きなかったとき、正常なのでステータスコード 200 OK を返し、リクエストデータをそのまま返す
	return c.JSON(http.StatusOK, data)
}

Postman を使って実際に受け取れている / 送り返せているか確認してみましょう。

INFO

omitempty を指定していると false, 0, 空文字("")は返ってきません。(omitempty は、ゼロ値の場合はそのフィールドを出力しないという意味でしたね。)