今天來寫把後端server拉起來的部分,後端我們使用Gin框架,並且當部屬上雲時會使用Lambda跑,本機端開發時會使用Ngrok,但不同情況因為初始化要做的事不同,所以跑的code也不一樣。
因此我們需要一個變數來區分,這邊我們使用GIN_MODE這個環境變數,當GIN_MODE是release時,會跑部屬上Lambda的部份,同時Gin本身在啟動時,如果讀到GIN_MODE是release也會將Gin切換成release模式,提升效能。而GIN_MODE本身default是debug模式,所以本機端也不用特別去設置這個環境變數。
那我們就先到Lambda上增加這個環境變數:
接著我們來寫main function,首先在lambda上要使用gin,我們可以使用lambda-go-api-proxy這個庫,非常方便
import外部依賴
import (
"context"
"log"
"github.com/aws/aws-lambda-go/events"
"github.com/aws/aws-lambda-go/lambda"
"github.com/gin-gonic/gin"
ginadapter "github.com/awslabs/aws-lambda-go-api-proxy/gin"
"github.com/line/line-bot-sdk-go/linebot"
)
做幾個會用到的全域變數,還有ginLambda的Handler
var (
ginLambda *ginadapter.GinLambda
lineClientLambda *linebot.Client
ssmsvc *ssm.SSM
)
func Handler(ctx context.Context, request events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) {
return ginLambda.ProxyWithContext(ctx, request)
}
我們透過gin.Mode()取得現在gin的模式,如果是ReleaseMode,我們就先去SSM拿Line的channel secret & access token,拿到後就可以New一個linebot的client出來了,接著透過傳給ginadapter.New()一個設定好的*gin.Engine就沒問題了。
func main() {
// env GIN_MODE="release"
rootCtx, _ := context.WithCancel(context.Background()) //nolint
if gin.Mode() == gin.ReleaseMode {
log.Println("Run on Lambda")
ssmsvc = ssm.NewSSM()
lineSecret, err := ssmsvc.FindParameter(rootCtx, ssmsvc.Client, "BAOSAVE_CHANNEL_SECRET")
if err != nil {
log.Println(err)
}
log.Println(lineSecret)
lineAccessToken, err := ssmsvc.FindParameter(rootCtx, ssmsvc.Client, "BAOSAVE_CHANNEL_ACCESS_TOKEN")
if err != nil {
log.Println(err)
}
lineClientLambda, err = linebot.New(lineSecret, lineAccessToken)
if err != nil {
log.Fatal(err)
}
log.Println("LineBot Create Success")
ginRouter := gin.New()
ginLambda = ginadapter.New(ginRouter)
lambda.Start(Handler)
} else if gin.Mode() == gin.DebugMode {
log.Println("Debug mode run on local")
}
}
這樣就很簡單完成Lambda連動Gin的部分了,這邊還沒有對ginRouter做相關的設定,我們先直接用gin.New()就好,後面幾天我們寫上一點Router和Application的部分後再做修改,那今天就先這樣,我們明天見~