APIGateway覚書
requestBodyでapplication/octet-stream
を受け付ける場合
↓エラーになる。Unsupported model type 'Content' in request schema for ...
x-amazon-apigateway-binary-media-types:
- applicatoin/octet-stream
paths:
/path:
put:
...
requestBody:
applicatoin/octet-stream:
schema:
type: string
format: binary
componentsに切り出すとなぜか成功する
x-amazon-apigateway-binary-media-types:
- applicatoin/octet-stream
paths:
/path:
put:
...
requestBody:
applicatoin/octet-stream:
schema:
$ref: "#/components/schemas/binarySchema"
components:
schemas:
binarySchema:
type: string
format: binary
なんだこれ
In method responses, schema definition must be of an object type and cannot be of primitive types. For example, "schema": { "type": "string"} is not supported. However, you can work around this using the following object type:
「In method responses」と書いてあるがrequestBodyでもこれに従わないといけないっぽい???
RestAPI 構築時の失敗集
- openapi.yamlのserviers.urlを複数書くとエラーになる
- nullableにしててもexampleとかで値にnullを指定してるとエラーになる(OpenAPI 3.0.1)
OpenAPIのbasePath
書かれてる通りにserversを記載してCloudFormationでRestAPIリソースを作成したがbasePathが解釈されず。
CfnのテンプレートにParametersでbasepathの設定を追加する必要があった
Api:
Type: AWS::ApiGateway::RestApi
Properties:
...
Parameters:
basepath: prepend # たぶんデフォルトはignoreになってるので反映されなかった
CLIのimport-rest-apiのparametersオプションを参照
CloudFront -> APIGateway -> Lambdaで接続してる時にLambdaにリクエストしたヘッダーがわたらない
RequestOriginPolicyをAllViewerにするとCloudFrontで403エラーになるようになった。
どうやらHostヘッダーをCft -> APIGWに渡すとエラーになるっぽい
REST API がProxy統合でLambdaと接続した場合、クライアントからのリクエストヘッダにContent-Length
が含まれていた場合、オリジンのLambda関数のeventにはContent-Length
が含まれない。
Proxy統合、かつ、CustomAuthorizerでLambda関数を経由させた場合、Authorizer関数の方のeventにはContent-Length
が含まれる。
オリジンにヘッダの値を渡したい場合はAuthorizer関数のレスポンスでcontextに値を含めると渡してやれる。
HTTPリクエストスマグリング攻撃などの対策のために勝手に削除してる??
ドキュメントからは削除される旨がみつからず・・
Amazon API Gateway important notesには「API Gateway enacts the following restrictions and limitations when handling methods with either Lambda integration or HTTP integration.」としてContent-Length(request)に関しては「Passthrough (generated based on body)」と書いてあるが、Proxy統合ではなくカスタム統合の場合だけなのかも
対応してないパスにリクエストが来た際に404返したい
RESOURCE_NOT_FOUND
を定義すればいいのかと思ったが、こちらを定義しても変わらず。そもそもデフォルトで404エラーだし
正しくはMISSING_AUTHENTICATION_TOKEN
を指定する必要があるよう。こちらはデフォルトで403なので404に変える
x-amazon-apigateway-gateway-response:
MISSING_AUTHENTICATION_TOKEN:
statusCode: 404
CloudFormationでRestApiを作成する際に、スタック更新すると、OpenAPIの定義で消したはずのAPIが残ってたりとかする場合がある。
そういうときはRestApiのMode属性をoverwrite
にしてやる。
デフォルトは
If you don't specify this property, a default value is chosen. For REST APIs created before March 29, 2021, the default is overwrite. For REST APIs created after March 29, 2021, the new API definition takes precedence, but any container types such as endpoint configurations and binary media types are merged with the existing API.
となっているので、明示的にoverwriteにしてやるほうがよい。
Resources:
Api:
Type: AWS::ApiGateway::RestApi:
Properties:
# ...
Mode: overwrite
event内のheadersとmultivalueHedaers
Lambda Proxy統合のときだけ?
- headers キーには、単一値のヘッダーのみを含めることができます。
- multiValueHeaders キーには、複数値のヘッダーや単一値のヘッダーを含めることができます。
- headers と multiValueHeaders の両方の値を指定した場合、API Gateway はそれらを単一のリストにマージします。同じキーと値のペアが両方で指定された場合にのみ、multiValueHeaders の値が、マージされたリストに表示されます。
- http1.1でリクエスト
- 同じヘッダで別の値を指定("X-Header-A"とする)
-
headers
にはどちらか一方の値が入る- どちらがどう選ばれてるかはわからない。先に指定したほう、というわけでもなさそう
-
multiValueHeaders
にはリスト形式で両方の値が含まれる - 大文字を含むものとすべて小文字にしたものをヘッダに指定("X-Header-A"と"x-header-a")
-
headers
のほうには"X-Header-A"のヘッダ名が来ているが、値は"x-header-a"で指定したほうだった -
multiValueHeaders
はヘッダ名が"X-Header-A"で、値はリストで両方の値が含まれる
-
- http2でリクエスト
- クライアントの指定時に大文字にしようが小文字にしようが、プロトコル的にすべて小文字に変換してからリクエストされる
- 同じく
headers
にはどちらかの値が入って、multiValueHeaders
には両方の値が含まれる
リクエストとレスポンスの例
GET HTTP1.1
X-Header-A: A
x-header-a: B
# apigw event
{
"event": {
"headers": {"X-Header-A": "A"}, # ここにはどっちの値が入るかよくわからん
"multiValueHeaders" : {"X-Header-A": ["A", "B"]}
}
}
GET HTTP2
x-header-a: A
x-header-a: B
# apigw event
{
"event": {
"headers": {"x-header-a": "A"}, # ここにはどっちの値が入るかよくわからん
"multiValueHeaders" : {"x-header-a": ["A", "B"]}
}
}
:::
カンマ区切りでリクエストしてもmultiValueHeaders
に別々の要素として含まれるわけではないみたい
GET HTTP1.1
X-Header-A: A,B
# apigw event
{
"event": {
"headers": {"X-Header-A": "A,B"},
"multiValueHeaders" : {"X-Header-A": ["A,B"]}
}
}
GET HTTP1.1
X-Header-A: A,B
X-Header-A: C
# apigw event
{
"event": {
"headers": {"X-Header-A": "A,B"}, # ここにはどっちの値が入るかよくわからん
"multiValueHeaders" : {"X-Header-A": ["C", "A,B"]}
}
}