はじめに
GoのGinフレームワークを書いている際に入力によって個数が変わるAPIを定義したので備忘録を残しておきます
私が間違っている情報等を書き込んでいるかもしれないので、ご指摘頂けると幸いです。
コード
標準入力の内容によってpathを定義するようなコードになります
動的にAPIを定義する部分はforを回してその中でハンドラを定義するだけですね
package main
import (
"fmt"
"strings"
"github.com/gin-gonic/gin"
)
func main() {
var in string
r := gin.Default()
// paths:hoge,huga
// のような入力を期待
fmt.Print("paths:")
fmt.Scan(&in)
paths := strings.Split(in, ",")
// forで回すことによって動的にAPIを定義
for _, path := range paths {
r.GET(path, func(ctx *gin.Context) {
ctx.JSON(200, gin.H{
"path": path,
})
})
}
r.Run()
}
考察
なぜfor文で回すことができるのか考察しました
考察なのであまりこれが当たっているという保証はありません
gin.Engine
Ginのgithubを見るとgin.Default()
で生成されているgin.Engine
は以下のURLに示されてるような構造体になっている
RouterGroup
という名前のフィールドがあるので見てみる
RouterGroup
Ginのgithubを見るとRouterGroupは以下のような構造体になっている
handlers
,basePath
などのフィールドがあるのでここでAPIのエンドポイント情報を記録してそう
type RouterGroup struct {
Handlers HandlersChain
basePath string
engine *Engine
root bool
}
同ファイルにおいてあったGET
メソッドを見るとhandle
というメソッドを使っている
func (group *RouterGroup) GET(relativePath string, handlers ...HandlerFunc) IRoutes {
return group.handle(http.MethodGet, relativePath, handlers)
}
以下handle
メソッド
func (group *RouterGroup) handle(httpMethod, relativePath string, handlers HandlersChain) IRoutes {
absolutePath := group.calculateAbsolutePath(relativePath)
handlers = group.combineHandlers(handlers)
group.engine.addRoute(httpMethod, absolutePath, handlers)
return group.returnObj()
}
group.engine.addRoute(httpMethod, absolutePath, handlers)
で最終的にgin.Engineの値としてルート情報を入れている考えられます
GET
等のメソッドはhandle
に依存しているkため、for文でGET等のメソッドを回してもハンドラーを作ることができる
参考文献