My Note

自己理解のためのブログ

APIGateway(HTTP API) + Lambda環境に echo(Goのweb Framework) を ServerlessFramework でデプロイする

はじめに

前回の記事で APIGatewayの REST API で EchoをAWS Lambdaで簡単なAPIをデプロイしました。 今回は、APIGatewayの HTTP API に変更します。差分について記述していきます。

yhidetoshi.hatenablog.com

変更部分

main.goのみを記載します。他のコードは前回の記事に記載しています。

  • main.go
package main

import (
    "context"
    "log"
    "yhidetoshi/go-echo-lambda/api/healthcheck"
    "yhidetoshi/go-echo-lambda/handler/auth"

    "github.com/aws/aws-lambda-go/events"
    "github.com/aws/aws-lambda-go/lambda"
    echoadapter "github.com/awslabs/aws-lambda-go-api-proxy/echo"

    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
)

//var echoLambda *echoadapter.EchoLambda   // APIGW(REST)
var echoLambda *echoadapter.EchoLambdaV2 // APIGW(HTTP) <--- V2 を利用する

func init() {
    log.Printf("echo cold start")

    e := echo.New()
    e.Use(middleware.Recover())
    e.Use(auth.BasicAuth())
    e.GET("/api/healthcheck", healthcheck.Healthcheck)

    //echoLambda = echoadapter.New(e) // APIGW(REST)
    echoLambda = echoadapter.NewV2(e) // APIGW(HTTP) <--- V2を利用する
}

func main() {
    lambda.Start(Handler)
}

//func Handler(ctx context.Context, req events.APIGatewayProxyRequest) (events.APIGatewayProxyResponse, error) { // APIGW(REST)
func Handler(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) { // APIGW(HTTP) // V2HTTPRequest と V2HTTPResponseを利用する
    return echoLambda.ProxyWithContext(ctx, req)
}

変更した部分の V2をそれぞれのライブラリで見てみると、APIGatewayの HTTP APIに対応している事がわかりました。

echoadapter "github.com/awslabs/aws-lambda-go-api-proxy/echo" から抜粋

aws-lambda-go-api-proxy/adapterv2.go at fb2efb1b553c23556ff79b843e2c11fa989db78f · awslabs/aws-lambda-go-api-proxy · GitHub

// EchoLambdaV2 makes it easy to send API Gateway proxy V2 events to a echo.Echo.
// The library transforms the proxy event into an HTTP request and then
// creates a proxy response object from the http.ResponseWriter
type EchoLambdaV2 struct {
    core.RequestAccessorV2

    Echo *echo.Echo
}

// NewV2 creates a new instance of the EchoLambda object.
// Receives an initialized *echo.Echo object - normally created with echo.New().
// It returns the initialized instance of the EchoLambdaV2 object.
func NewV2(e *echo.Echo) *EchoLambdaV2 {
    return &EchoLambdaV2{Echo: e}
}

// Proxy receives an API Gateway proxy V2 event, transforms it into an http.Request
// object, and sends it to the echo.Echo for routing.
// It returns a proxy response object generated from the http.ResponseWriter.
func (e *EchoLambdaV2) Proxy(req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {
    echoRequest, err := e.ProxyEventToHTTPRequest(req)
    return e.proxyInternal(echoRequest, err)
}

// ProxyWithContext receives context and an API Gateway proxy V2 event,
// transforms them into an http.Request object, and sends it to the echo.Echo for routing.
// It returns a proxy response object generated from the http.ResponseWriter.
func (e *EchoLambdaV2) ProxyWithContext(ctx context.Context, req events.APIGatewayV2HTTPRequest) (events.APIGatewayV2HTTPResponse, error) {
    echoRequest, err := e.EventToRequestWithContext(ctx, req)
    return e.proxyInternal(echoRequest, err)
}

github.com/aws/aws-lambda-go/events から抜粋

aws-lambda-go/apigw.go at 67965281f13ade83c809a78acdac095e84d701fd · aws/aws-lambda-go · GitHub

// APIGatewayV2HTTPRequest contains data coming from the new HTTP API Gateway
type APIGatewayV2HTTPRequest struct {
    Version               string                         `json:"version"`
    RouteKey              string                         `json:"routeKey"`
    RawPath               string                         `json:"rawPath"`
    RawQueryString        string                         `json:"rawQueryString"`
    Cookies               []string                       `json:"cookies,omitempty"`
    Headers               map[string]string              `json:"headers"`
    QueryStringParameters map[string]string              `json:"queryStringParameters,omitempty"`
    PathParameters        map[string]string              `json:"pathParameters,omitempty"`
    RequestContext        APIGatewayV2HTTPRequestContext `json:"requestContext"`
    StageVariables        map[string]string              `json:"stageVariables,omitempty"`
    Body                  string                         `json:"body,omitempty"`
    IsBase64Encoded       bool                           `json:"isBase64Encoded"`
}

ServerlessFramework

www.serverless.com

  • serverless.yamlの変更部分
    • 全体は前回の記事に記載しています
functions:
  GoEchoLambda:
    handler: main
    role: GoEchoLambda
    timeout: 10
    description: go echo lambda test 
    memorySize: 128
    events:
      - httpApi:  # httpApi に変更する
      #- http:
          path: /api/{proxy+}
          method: any
          #integration: lambda

動作確認

❯ curl -u test:pass https://xxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/api/healthcheck
{"status":200,"message":"Success to connect echo"

さいごに

今回は、前回の記事においてAPIGatewayの REST API ではなく HTTP API を使うように変更しました。 HTTP APIでも利用できる事を確認できました!

ソースコード

github.com