Goのルーティングの設定の基本

備忘録です。

Goの基本的なルーティングの設定を記載します。

フレームワークである gin を使って説明を行っていきます。

## ファイルにルーティングを設定

```go
package main

import (
	"log"
	"net/http"

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

func main() {
	r := gin.Default()     // ginのEngineインスタンスを生成
	r.GET("/", sampleFunc) // ルーティング設定
	r.Run()                // サーバに接続。HTTPリクエストを受け付ける
}

func sampleFunc(c *gin.Context) {
	log.Println("I am sampleFunc")
	c.JSON(http.StatusOK, gin.H{"message": "HELLO!"})
}
}
```

コマンド実行

```bash
go run main.go

[GIN-debug] [WARNING] Creating an Engine instance with the Logger and Recovery middleware already attached.

[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
 - using env:	export GIN_MODE=release
 - using code:	gin.SetMode(gin.ReleaseMode)

[GIN-debug] GET    /                         --> main.sampleFunc (3 handlers)
[GIN-debug] [WARNING] You trusted all proxies, this is NOT safe. We recommend you to set a value.
Please check https://pkg.go.dev/github.com/gin-gonic/gin#readme-don-t-trust-all-proxies for details.
[GIN-debug] Environment variable PORT is undefined. Using port :8080 by default
[GIN-debug] Listening and serving HTTP on :8080
```

デフォルトは `[localhost:8080](http://localhost:8080)` なのでHTTPリクエストを投げてみます

```bash
curl localhost:8080
{"message":"HELLO!"}%
```

`{"message":"HELLO!"}` は sampleFunc 関数の返り値である `c.JSON(http.StatusOK, gin.H{"message": "HELLO!"})` の箇所です。jsonで値を返しています。

サーバのログには以下のように記載されます

```bash
2021/12/04 04:03:22 I am sampleFunc
[GIN] 2021/12/04 - 04:03:22 | 200 |    1.557333ms |             ::1 | GET      "/"
```

## URLパラメータを取得する

`Param` を使用するとルーティングに設定されているパラメータを取得できます。

```go
package main

import (
	"log"
	"net/http"

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

func main() {
	r := gin.Default()     // ginのEngineインスタンスを生成
	r.GET("/", sampleFunc) // ルーティング設定
	r.GET("/:id", sampleFunc2)
	r.Run() // サーバに接続。HTTPリクエストを受け付ける
}

func sampleFunc(c *gin.Context) {
	log.Println("I am sampleFunc")
	c.JSON(http.StatusOK, gin.H{"message": "HELLO!"})
}

func sampleFunc2(c *gin.Context) {
	log.Println("I am sampleFunc2")
	id := c.Param("id") // 変数 id　に格納
	log.Println("id:", id)
	c.JSON(http.StatusOK, gin.H{"status": id}) // 返却
}
```

ルーティングの文字列を取得できてることが分かるかと思います。

```bash
curl localhost:8080/hoge
{"status":"hoge"}%

curl localhost:8080/fuga
{"status":"fuga"}%
```

ログにもきちんと出力されています。

```go
2021/12/04 04:24:05 I am sampleFunc2
2021/12/04 04:24:05 id: hoge
[GIN] 2021/12/04 - 04:24:05 | 200 |    2.192375ms |             ::1 | GET      "/hoge"
```

複数指定も可能です。

サンプルとして sampleFunc3 を実装しました。

```go
package main

import (
	"log"
	"net/http"

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

func main() {
	r := gin.Default()     // ginのEngineインスタンスを生成
	r.GET("/", sampleFunc) // ルーティング設定
	r.GET("/:id", sampleFunc2)
	r.POST("/fuga/:aaa/hoge/:iii", sampleFunc3)
	r.Run() // サーバに接続。HTTPリクエストを受け付ける
}

func sampleFunc(c *gin.Context) {
	log.Println("I am sampleFunc")
	c.JSON(http.StatusOK, gin.H{"message": "HELLO!"})
}

func sampleFunc2(c *gin.Context) {
	log.Println("I am sampleFunc2")
	id := c.Param("id") // 変数 id　に格納
	log.Println("id:", id)
	c.JSON(http.StatusOK, gin.H{"status": id}) // 返却
}

func sampleFunc3(c *gin.Context) {
	log.Println("I am sampleFunc3")
	log.Println("aaa:", c.Param("aaa"))
	log.Println("iii:", c.Param("iii"))
	c.JSON(http.StatusAccepted, gin.H{
		"aaa": c.Param("aaa"),
		"iii": c.Param("iii"),
	})
}
```

リクエスト結果

```go
curl -H "Content-Type: application/json" -X POST http://localhost:8080/fuga/hello/hoge/world
{"aaa":"hello","iii":"world"}%
```

ログ

```go
2021/12/04 04:34:28 I am sampleFunc3
2021/12/04 04:34:28 aaa: hello
2021/12/04 04:34:28 iii: world
[GIN] 2021/12/04 - 04:34:28 | 202 |     363.375µs |             ::1 | POST     "/fuga/hello/hoge/world"
```

ちなみに `r.Run()` に引数入れるとポート変更出来ます。

```go
func main() {
	r := gin.Default()     // ginのEngineインスタンスを生成
	r.GET("/", sampleFunc) // ルーティング設定
	r.GET("/:id", sampleFunc2)
	r.POST("/fuga/:aaa/hoge/:iii", sampleFunc3)
	r.Run(":3000") // サーバに接続。HTTPリクエストを受け付ける
}
```

```go
curl localhost:8080/hoge
curl: (7) Failed to connect to localhost port 8080: Connection refused

curl localhost:3000/hoge
{"status":"hoge"}%
```