4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS API Gateway がリクエストヘッダーを小文字にしてしまう時の解決策 (golang)

Last updated at Posted at 2020-08-24

ここ最近業務で API Gateway + Lambda を使った開発を行っており、API Gateway の振る舞いで注意しなければならない点を見つけたので、解決方法も添えて記事にしたいと思います。開発言語は Go言語です

AWS API Gateway がリクエストヘッダーを小文字にしてしまう

  • 今回使用するサンプルプログラムです
package main

import (
	"errors"
	"fmt"
	"log"

	"github.com/aws/aws-lambda-go/events"
	"github.com/aws/aws-lambda-go/lambda"
	"github.com/aws/aws-lambda-go/lambdacontext"
)

type (
	request  = events.APIGatewayProxyRequest
	response = events.APIGatewayProxyResponse
)

// handler handles AWS Lambda execution.
func handler(ctx context.Context, r request) (response, error) {
	if _, ok := lambdacontext.FromContext(ctx); !ok {
		return response{StatusCode: http.StatusBadRequest}, errors.New("not invoked from aws lambda")
	}
	log.Print(r.Headers)
	accept, _ := r.Headers["Accept"] // 実際は accept としないと取得できない
	if == strings.Contains(accept, "application/json") {
		return response{StatusCode: http.StatusOK, Body:"{}"}, nil
	}
	return response{StatusCode: http.StatusOK, Body: fmt.Sprintf("It Works! path=%s", r.Path)}, nil
}

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

サンプルプログラムでは Accept ヘッダーが application/json だった場合に空の json を返します。

今回の一例ですが、下記のようなリクエストを送信したとします。

curl -X GET -H "Accept:application/json" https://hogehoge

これが API Gateway を通って Lambda 側にきた時には Accept → accept になっていて、r.Headers["Accept"]では取得できません。
そもそもRFCの定義では、リクエストヘッダーは小文字大文字を区別しないとなっています。
「とりあえず全部小文字に変換しておくから、アプリケーション側で取得する時は小文字で取得してね」という事なのでしょうかね?

大文字、小文字の区別なく取得できるようにするには

全て小文字で書かなければならないのはとてもモヤモヤします。この問題に対して有効な解決策が、Lambda の SDK 開発の PR の議論のなかにありました。
vents.APIGatewayProxyRequest の header を net/http の header に置き換えてしまうというやり方です。
net/http の Header は CanonicalHeaderKey() を用いて正規化されるので、AcceptでもacceptでもACCEPTでも問題ありません。


headers := http.Header{}
for header, values := range r.MultiValueHeaders {
	for _, value := range values {
		headers.Add(header, value)
	}
}

headers.Get("Accept")

golang で Lambda 開発を行う方は是非参考にしてください。

4
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?