🫠

【AWS】APIGateWayをフロントから叩くまで

2024/07/23に公開

今回はREST APIを作る。

流れ

  1. DynamoDBのテーブル作成
  2. Lambda関数の作成
  3. API Gatewayの作成
  4. 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でもやってみたよ
https://zenn.dev/antapp/articles/88cfab11861dfe
https://zenn.dev/antapp/articles/b30066d835d54e

Discussion