[Go/gin] GETリクエストに配列でパラメータを渡す方法


結論

  • GinコンテキストのQueryArray()をつかって受け取る
    • gc.QueryArray("params[]")
    • gc.GetQueryArray("params[]")
  • 構造体にバインドするには、下記の通り
type Req struct {
    Params []int `form:"params[]"`
}

実装

複数ステータスなどの条件で検索したい時に、フロントエンドから配列でパラメータを送れるようになります。
handlerまでのサンプルを載せておきます。

curl -X GET 'http://localhost/hoge/path?params[]=1&params[]=2'
main.go
package main

import (
	"net/http"

	"github.com/gin-gonic/gin"
)

func main() {
	gin.SetMode("debug")
	e := gin.Default()

	assignHandler(e)

	if err := e.Run(":80"); err != nil {
		panic(err)
	}
}

func assignHandler(e *gin.Engine) {
	h := e.Group("hoge")
	{
		h.GET("/path", GetHogePath)
	}
}

type GetHogePathRequest struct {
	Params []int `form:"params[]" url:"params[]"`
}

func GetHogePath(gc *gin.Context) {
	var req GetHogePathRequest
	if err := gc.Bind(&req); err != nil {
		gc.JSON(http.StatusBadRequest, err)
		return
	}
	gc.JSON(http.StatusOK, req.Params)
}

テスト実装

main_test.go
package main

import (
	"net/http/httptest"
	"testing"

	"github.com/gin-gonic/gin"
)

func TestGetHogePath(t *testing.T) {
	cases := []struct {
		query      string
		expected   string
		statusCode int
	}{
		{"/hoge/path?params[]=1", "[1]", 200},
		{"/hoge/path?params[]=1&params[]=2", "[1,2]", 200},
	}

	for _, c := range cases {
		// Engine不要のため無視
		res := httptest.NewRecorder()
		gc, _ := gin.CreateTestContext(res)

		req := httptest.NewRequest("GET", c.query, nil)
		gc.Request = req

		GetHogePath(gc)

		targetStatusCode := res.Code
		if res.Code != c.statusCode {
			t.Errorf("expected: %v, input: %v", c.statusCode, targetStatusCode)
		}
		targetWord := res.Body.String()
		if targetWord != c.expected {
			t.Errorf("expected: %v, input: %v", c.expected, targetWord)
		}
	}
}

参考