目次
とある日
LambdaとAPI Gatewayを使って初めて開発してたときの備忘録。
この記事では、API Gatewayのみの備忘録を記述しています。
職場の環境で作成していたので、この記事では、実際のコードや画面をお見せすることはできません。
基本的に文章ベースで記述します。
LambdaやAPI Gatewayでハマったポイントをまとめてるのでこれから作成する人は気をつけてください。
それとこの開発は、2021年6月3日頃の仕様に基づいて作成しています。
AWS構成図
サービス説明
EC2
HTMLやCSS,JavaScriptなど静的サイト
-
EC2からのAPIアクセスのエンドポイント
Lambda
RDS
コンテンツを格納
簡単なサイトを構築している。
サイトで必要な情報はデータベースに格納している。
API Gateway
規模に応じた API の作成、維持、保護を行います
Amazon API Gateway(規模に応じた API の作成、維持、保護)| AWS
初めてのサーバーレスアプリケーション開発 ~API GatewayからLambdaを呼び出す~ | DevelopersIO
↑構築で参考にした記事
JavaScriptでAPIへのエンドポイントとして活用しました。
他にも、S3のバケット内の静的ファイルへのアクセスをするにも活用しました。
今まで、API開発をPythonで行っていたことのサーバーサイドのエンドポイントの設定をこのサービスで行う感じでした。
今まで、プログラムで作成していたリクエストやレスポンスが簡単に作成編集ができるサービス。
今回は、APIのエンドポイントとして活用した際の備忘録のみを記述します。
リクエスト処理
POSTとGETのリクエストの構成をしっかりと理解する必要性がある。
リクエストボディ、リクエストパラメータで値を受け取る流れが、
API Gatewayでやるとまた別のやり方になるので少し大変でした。
リクエスト値受け取り方法
リクエスト値をどうやってLambdaに渡すのかがPOST
とGET
で違うので苦戦しました。
変数で値を受け取って、任意の形式に変換して次の処理に渡す流れとなります。
{ "name" : "$input.params('name')", "body" : $input.json('$.mykey') }
GET
送信時クエリ文字列にname
で指定した値が$input.params('name')
に格納される。
POST
送信時リクエストボディオブジェクトにmykey
で指定した値が$input.json('$.mykey')
に格納される。
という使い方をしました。
他にも、変数を使ってリクエスト値を操作できますが、Lambdaで処理するためシンプルな構造体にしていました。
GETはクエリ文字列に「name=test」を指定するとマッピングテンプレートで指定した形となってLambdaに処理が遷移する。
POSTはリクエスト本文に、Lambdaの方でテストしてる内容自体をコピーしていました。
{ "mykey":"test" }
ハマった話
リクエスト値を受け流すだけでも苦戦しましたが、他にもいくつかハマった話があるので簡潔に述べます。
POSTでハマったところ
もちろんAPI GatewayでCORSの設定は許可してある。
さらに、LambdaでCORSの許可したパラメータを返却もしている。
解決方法は、フロントサイドが原因だった。
自分の場合は、クライアント側jqueryのajaxで、contentTypeでapplication/json;charset=utf-8が未記述だったので追加で解決しました。
文字コードはあってもなくても変わらないです。多分。
プライベート設定
API Gatewayをプライベート設定で構築可能だったのでセキュリティ向上のために設定を行おうとした。
しかし、色々と試行錯誤したけどできなかった。
妥協する形となりましたが、要件定義的に大丈夫かと思い、API GatewayのリソースポリシーでIPの固定だけでアクセス制限を行いました。
VPCエンドポイントを設定したり、リソースポリシーの設定をしてもできなかったです。
APIのセキュリティを簡単に高めたいのであれば、APIキーを使うのが早い気がします。
API Gatewayには下記のような問題もあるので、プライベートを使いこなすのはかなり難しいと感じました。
CORS設定
GETでAPIの通信を行っているときに出た話。
OPTIONS設定をしてもできなかったので、GETやPOSTにも同様にの設定を行いました。
ただ設定が反映されるの少し時間がかかるみたいです。
〆
フロントサイドのプログラムの修正や、CORSなど他要因が多すぎてトラブルの切り分けがすごく大変でした。