Open10

APIGateway覚書

えんぶんえんぶん

requestBodyでapplication/octet-streamを受け付ける場合

↓エラーになる。Unsupported model type 'Content' in request schema for ...

openapi.yaml
x-amazon-apigateway-binary-media-types:
  - applicatoin/octet-stream
paths:
  /path:
    put:
      ...
      requestBody:
        applicatoin/octet-stream:
          schema:
            type: string
            format: binary

componentsに切り出すとなぜか成功する

openapi.yaml
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

なんだこれ

えんぶんえんぶん

RestAPI 構築時の失敗集

  • openapi.yamlのserviers.urlを複数書くとエラーになる
  • nullableにしててもexampleとかで値にnullを指定してるとエラーになる(OpenAPI 3.0.1)
えんぶんえんぶん

OpenAPIのbasePath

https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-import-api-basePath.html

書かれてる通りにserversを記載してCloudFormationでRestAPIリソースを作成したがbasePathが解釈されず。
CfnのテンプレートにParametersでbasepathの設定を追加する必要があった

template.yaml
Api:
  Type: AWS::ApiGateway::RestApi
  Properties:
    ...
    Parameters:
      basepath: prepend  # たぶんデフォルトはignoreになってるので反映されなかった

CLIのimport-rest-apiのparametersオプションを参照

https://awscli.amazonaws.com/v2/documentation/api/latest/reference/apigateway/import-rest-api.html

えんぶんえんぶん

CloudFront -> APIGateway -> Lambdaで接続してる時にLambdaにリクエストしたヘッダーがわたらない
RequestOriginPolicyをAllViewerにするとCloudFrontで403エラーになるようになった。
どうやらHostヘッダーをCft -> APIGWに渡すとエラーになるっぽい

https://qiita.com/folky_records/items/2a231b14c08be82a183a

https://stackoverflow.com/questions/71367982/cloudfront-gives-403-when-origin-request-policy-include-all-headers-querystri

えんぶんえんぶん

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返したい

https://docs.aws.amazon.com/apigateway/latest/developerguide/supported-gateway-response-types.html

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にしてやる。

https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-apigateway-restapi.html#cfn-apigateway-restapi-mode

デフォルトは

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統合のときだけ?

https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/set-up-lambda-proxy-integrations.html

  • 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"]}
  }
}