ルートの登録
この章では、Go-Sail でのルート登録方法について解説します。
はじめに
Go-Sail は Gin を HTTP サービスエンジンとして過度なラッピングなしで採用しているため、基本的な使い方は Gin 本家の使用方法と全く同じです。
新しいルートを登録する
前の章ではスケルトンサービスを起動し、/hello というルートを登録しました。ここでは新しくユーザーログイン用の /login というルートを追加してみましょう。
main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
"github.com/keepchen/go-sail/v3/sail/config"
)
var (
conf = &config.Config{}
registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
sail.Response(c).Data("login successfully!")
})
}
)
func main() {
sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch()
}
ハイライトされているコードを見ると、このルートは POST リクエストのみ受け付けて、「login successfully!」という応答を返していることが分かります。
次に、この機能を拡張していきます。
リクエストパラメーターのバインド
HTTPの POST リクエストでパラメーターを受け渡し・取得する方法はいくつかありますが、Gin の自動型判定とパラメータバインディング機能を使うことで簡単にできます。
まず、リクエストパラメーターの構造体を定義します。これにより後続の利用やコードの可読性が向上します。
main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
"github.com/keepchen/go-sail/v3/sail/config"
)
type LoginRequest struct {
Username string `json:"username" form:"username" query:"username"`
Password string `json:"password" form:"password" query:"password"`
}
var (
conf = &config.Config{}
registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
sail.Response(c).Data("login successfully!")
})
}
)
func main() {
sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch()
}
次に、/login ルート内で受信したデータを定義済みの構造体へバインドします。
main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
"github.com/keepchen/go-sail/v3/sail/config"
)
type LoginRequest struct {
Username string `json:"username" form:"username" query:"username"`
Password string `json:"password" form:"password" query:"password"`
}
var (
conf = &config.Config{}
registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
var loginRequest LoginRequest
c.ShouldBind(&loginRequest)
sail.Response(c).Data("login successfully!")
})
}
)
func main() {
sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch()
}
リクエストパラメーターの検証
通常はリクエストパラメーターの検証が必要となります。ここでは例として、ユーザー名とパスワードが正しいかどうかをチェックする処理を追加します。
main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
"github.com/keepchen/go-sail/v3/sail/config"
)
type LoginRequest struct {
Username string `json:"username" form:"username" query:"username"`
Password string `json:"password" form:"password" query:"password"`
}
var (
conf = &config.Config{}
registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
var loginRequest LoginRequest
c.ShouldBind(&loginRequest)
if loginRequest.Username != "go-sail" || loginRequest.Password != "password" {
sail.Response(c).Failure("login failed, username or password not match!")
return
}
sail.Response(c).Data("login successfully!")
})
}
)
func main() {
sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch()
}
認証情報の発行
ログインが成功したユーザーにはサービスリソース利用のための認証情報(トークン等)を発行しましょう。
main.go
package main
import (
"github.com/gin-gonic/gin"
"github.com/keepchen/go-sail/v3/sail"
"github.com/keepchen/go-sail/v3/sail/config"
)
type LoginRequest struct {
Username string `json:"username" form:"username" query:"username"`
Password string `json:"password" form:"password" query:"password"`
}
var (
conf = &config.Config{}
registerRoutes = func(ginEngine *gin.Engine) {
ginEngine.GET("/hello", func(c *gin.Context){
sail.Response(c).Data("hello world!")
})
ginEngine.POST("/login", func(c *gin.Context){
var loginRequest LoginRequest
c.ShouldBind(&loginRequest)
if loginRequest.Username != "go-sail" || loginRequest.Password != "password" {
sail.Response(c).Failure("login failed, username or password not match!")
return
}
token := "this-is-a-valid-token"
sail.Response(c).Data(token)
})
}
)
func main() {
sail.WakeupHttp("go-sail", conf).Hook(registerRoutes, nil, nil).Launch()
}
このトークン(認証情報)を使ってサービスリソースへアクセスできるようになります。リクエスト時はトークンの有効性を確認し、認証を行います。
ヒント
さらに詳しい利用法は Gin公式ドキュメント をご覧ください。