🐷

【Gin+Docker】Railsライクなディレクトリ構成で簡単なアプリを作ってみる (2)Controller&ルーティング編

2023/08/12に公開

今回はControllerとルーティングの部分を作っていきます。

前: 環境構築&Hello, world編
後: そのうち

前回の記事の部分まで進んでいるという前提で進めていきます。

Controller

今回は、ユーザーの詳細を表示するページのControllerを作成していきます。
Controllerの責務は、各アクションにおいて、パラメータなどの入力の受け取りと、適切なModelへの値の受け渡しとなります。
ただし、Modelの部分などはまだ作成していないため、ダミーのjsonを返すようにします。

Railsにならってapp/controllersをController用のディレクトリとしたいので、mkdirでを作成しておきます。

$ mkdir -p app/controllers

今回はusers_controller.goのshowアクションに記述します。関数名はUserShowとします。

アクション用の関数は、引数として*gin.Contextを受け取る必要があります。

app/contorllers/users_controller.go
package controllers

import (
	"net/http"

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

func UserShow(c *gin.Context) {
	c.JSON(http.StatusOK, gin.H{
		"user_id": 1,
		"name": "name",
	})
}

URLからidを受け取る

Railsにおけるshowアクションではhttps://hoge.com/users/1のようにURLでidを指定します。
これは*gin.ContextのParamsメソッドにより実現できます。

app/contorllers/users_controller.go
package controllers

import (
	"net/http"
	"strconv"

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

func UserShow(c *gin.Context) {
	user_id, _ := strconv.Atoi(c.Param("id")) // idの部分はルーティングの際に指定する
	c.JSON(http.StatusOK, gin.H{
		"user_id": user_id,
		"name": "name",
	})
}

なお、URLから取得する際全て文字列として扱われるので、数値などで扱いたい場合は型変換する必要があります。
上のコードではstrconv.Atoi()を使って数値に変換しています。

クエリパラメータを受け取る

今回は使用しませんが、クエリパラメータを受け取る際は、*gin.ContextのQueryメソッドにより実現できます。

user_id, _ := strconv.Atoi(c.Query("id")) // http://hoge.com/users?id=1のようなリクエストで有効

ルーティング

先ほど作った関数を使うようにルーティングを登録していきます。なおHello, world!は消します。

同様にRailsにならい、app/config/router.goでルーティングを管理します。
SetRoutingという関数を作成しルーティングを定義していきます。

app/config/router.go
package config

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

	"gin_sample/app/controllers"
)

func SetRouting(e *gin.Engine) {
	e.GET("/users/:id", controllers.UserShow)
}

パスを/users/:idとしていますが、:idとすることによりコントローラ側からc.Params("id")で呼び出せるようになっています。

次に、作成したSetRoutingmain.goで呼び出します。

app/main.go
package main

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

	"gin_sample/config"
)

func main() {
	engine := gin.Default()

	config.SetRouting(engine)

	engine.Run(":8080")
}

localhost:8080/users/1にアクセスして、{"name":"name","user_id":1}が表示されたら成功です(nameとuser_idは入れ替わるかもしれません)。
1の部分を3など別の数字に変えると、レスポンスのuser_idも同様に変化するはずです。

ルーティングをグループ化する

今回users_controllerではshowアクションのみ記述していました。
ただ、今後拡張するに当たってindexアクションやcreateアクションなど、他のアクションも作成したくなるかもしれません。
その際、/users以下でルーティングをまとめます。

app/confing/routes.goSetRoutingを以下のようにします。

app/config/routes.go
func SetRouting(e *gin.Engine) {
	users := e.Group("/users")
	{
		users.GET("/:id", controllers.UserShow)
	}
}

users:= e.Group("/users")とまとめることにより、以下ではusers.GET("/:id", ...)とパスを短くかけるようになります。

終わりに

ここまでのコードは以下に置いています。
リポジトリ
今回のコミット

次はDB設定とモデル編を予定しています。

参考

Discussion