Ginを使ったGo API開発の初歩(BindQuery編)

以下の記事でGinをインストールしてGo APIの実装を始めました。今日はBindQueryを導入し、フォームに応じて出力を変更するAPIを実装します。

Ginを使ったGo API開発の初歩

  • BindQueryとは
  • BindQueryの実装
  • APIの確認

BindQueryとは


BindQueryとは、golangにおいてクエリパラメータをバインドする機能です。

この機能によってフォームに応じた返答を行うことができます。例えば、日付をフォームに入力したら、その日付のデータのみ返すことができます。このようにBindQueryを使うことで、より使い勝手のいいAPIを作成できるようになります。

BindQueryの実装


BindQueryを実装します。

グループに所属するメンバーを表示するbind_query.goを作成します。存在するグループはgroup1とgroup2を用意し、クライアントはnameフォームの値にグループ名を入力することで表示するグループを切り替えます。指定したグループ名が存在しない場合は、httpリクエストステータスを400にして「There are no groups」を返します。

package main

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

type Group struct {
	Name    string `form:"name"`
}

var GROUP1_MEMBER_LIST = [...] gin.H{ gin.H{"name": "koratta01"}, gin.H{"name": "koratta02"} }
var GROUP2_MEMBER_LIST = [...] gin.H{ gin.H{"name": "ratta01"}, gin.H{"name": "ratta02"} }

var GROUP_MEMBER_LIST = gin.H{
	"group1":  gin.H{ "member": GROUP1_MEMBER_LIST },
	"group2":  gin.H{ "member": GROUP2_MEMBER_LIST },
}

func main() {
	route := gin.Default()
	route.Any("/member", getGroupMember)
	route.Run(":8080")
}

func getGroupMember(c *gin.Context) {
	var group Group
	if c.BindQuery(&group) == nil {
		if member_list, exists := GROUP_MEMBER_LIST[group.Name]; exists {
			c.JSON(200, member_list)
		} else {
			c.String(400, "There are no groups")
		}
	}
}

APIの確認


作成したbind_query.goを実行してAPIを確認します。

$ go run bind_query.go

別ターミナルで以下のコマンドを実行すると、グループ名に所属するメンバーリストが取得できることを確認できます。

$ curl --request GET 'http://localhost:8080/member?name=group1'
{"member":[{"name":"koratta01"},{"name":"koratta02"}]}
$ curl --request GET 'http://localhost:8080/member?name=group2'
{"member":[{"name":"ratta01"},{"name":"ratta02"}]}
$ curl --request GET 'http://localhost:8080/member?name=group3'
There are no groups

bind_query.goのログを確認すると以下の通り、所属するグループだけステータスが200となっています。

[GIN] 2020/07/14 - 22:38:15 | 200 |     199.543µs |             ::1 | GET      "/member?name=group1"
[GIN] 2020/07/14 - 22:38:21 | 200 |      51.177µs |             ::1 | GET      "/member?name=group2"
[GIN] 2020/07/14 - 22:38:26 | 400 |      57.617µs |             ::1 | GET      "/member?name=group3"

Postで送信したときの挙動も確認すると、Getではメンバーリストが返ってきたグループ名でも「There are no groups」が返ってきています。これはBindQueryがPostデータをバインドしないからです。

$ curl --request POST 'http://localhost:8080/member?name=group3'
There are no groups
[GIN] 2020/07/14 - 22:45:10 | 400 |      56.774µs |             ::1 | POST     "/member?name=group3"

以上です。