【AWS】APIGateWayをフロントから叩くまで
今回はREST APIを作る。
流れ
- DynamoDBのテーブル作成
- Lambda関数の作成
- API Gatewayの作成
- CORS対策 (APGatewayで呼び出す)
## 1.DynamoDBのテーブル作成
テーブル名「Users」、カラムは「UserId」(文字列)
2.Lambda関数の作成
GETメソッド APIの作成
「関数名」と「デフォルトの実行ロールの変更」のみ設定。
あとの設定はそのままでOK。
メソッドの内容は以下を設定。
import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { ScanCommand } from "@aws-sdk/lib-dynamodb";
export const handler = async (event) => {
const client = new DynamoDBClient({ region: リージョン });
const params = {
TableName: 手順1で作成したテーブル名,
};
const command = new ScanCommand(params);
const data = await client.send(command);
const response = {
statusCode: 200,
body: JSON.stringify(data.Items),
};
return response;
};
「FIle」タブから「Save」をクリック。
「Deploy」をクリックして更新が完了。
「テスト」をクリックしてイベントを設定する。
イベントはなんでもよいので、名前に「test」とつけて「作成」し、
「Deploy」をクリックする。
レスポンスが正常に来ていたらOK。
バージョン
「新しいバージョンを作成」から、バージョンは「1」で作成。
エイリアス
エイリアスは「新しいエイリアスを作成」から「dev」で作成。
完了したら、ARNをコピーして控えておく。
arn:aws:lambda:リージョン:数字:function:GetUsers:dev
これでデータ取得APIの作成が完了。
Authメソッドの作成
メモ忘れてた。。。
(別途記事で公開するかも)
3.API Gatewayの作成
「リソースを作成」、リソース名にエンドポイントの名前を指定する。
「メソッドを作成」でGETやPOSTなどを選択する。
「Lambda関数」を選択。
実行したいLambda関数のARNコードを指定する。
このとき、Lambda関数のエイリアスのARNコード(末尾に:devなどがついているもの)を指定すること。
メソッドの認可が「NONE」になっているので、Lambda関数のAUTHを経由するように指定する。「編集」でオーソライザーに作成したLambda関数のAuthを指定する。
フロントで叩く前にcurlでAPIの確認
GETメソッド
curl -XGET -H 'authorizationToken: トークン' https://エンドポイントになるパス
POSTメソッド
curl -XPOST -H 'authorizationToken: トークン' -H 'Content-Type: application/json' -d '{"UserName":"hoge taro", "Age":"30"}' https://エンドポイントになるパス
PUTメソッド
curl -XPUT -H 'authorizationToken: トークン' -H 'Content-Type: application/json' -d '{"UserName":"Update taro", "Age":"40"}' https://エンドポイントになるパス
DELETEメソッド
curl -XDELETE -H 'authorizationToken: トークン' https://エンドポイントになるパス
APIキー
APIキーごとにアクセス数の制限をかけたりする。
使用用途として、認証に用いるのではないので、”キー”というのは鍵のキーではなくキーバリューのキーというイメージ。
curlに以下を追加
“x-api-key: 生成したキー”
curl -XGET -H 'authorizationToken: トークン' -H 'x-api-key: 生成したキー' https://エンドポイントになるパス
4.CORS対策(フロントからUsersAPIを叩く)
フロントからUsersAPIを叩く。
(私はTypeScriptのReactで叩いた)
const url = 'https://エンドポイントになるパス';
await axios.get(url, {
// withCredentials: true,
headers: {
'authorizationToken': 'トークン',
'x-api-key': '生成したキー'
}
}).then(res => {
console.log('成功レスポンス', res.data);
void swal("Success", res.data.message, "success").then(response => {
console.log('成功', response);
});
}).then(err => {
console.log('失敗レスポンス', err);
void swal("Failed", "error").then(response => {
console.log('失敗', response);
});
});
シンプルリクエストではない場合のCORSはプリフライトが実行される。
APIGatewayのOPTIONメソッドの設定の認可をNONEにしておく。
APIキーもFalseにしておく。
プリフライトはなんのチェックもなく飛ぶようにして、
次に実行されるリクエストで認可やAPIキーをヘッダーから取得するという流れ。
API Gatewayの**「CORSを有効にする」ボタンは、プロキシ統合の際は嘘**なので、設定しても効かない。
統合レスポンスが、プロキシ統合になっている状態は、Lambadaのレスポンスがそのまま出ていくという意味。
なので、CORSエラーと表示されていても実はheaderが足りないエラーの場合もある。
その場合は、Lambda関数側でヘッダーをつけてやればOK。
Lambda関数内はこんな感じで返せばOK。
(AllowOriginは実際は*じゃなくてちゃんと指定すること)
const response = {
statusCode: 200,
body: JSON.stringify(data.Items),
headers: {
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET',
"Access-Control-Allow-Headers": "Content-Type, authorizationtoken"
}
};
return response;
同じようなことをSAMでもやってみたよ
Discussion