初めてでもわかるAWS Lambdaの使い方（GET通信編）

# はじめに
AWS Lambdaを初めて使う人，もしくはその状態に近い人でもわかりやすいよう記事を書いていきます．
今回作成するシステムの仕様は以下です．

1. ランダムな値をLambdaが生成する
1. API GatewayでLambdaのAPIを作成する
1. ReactでAPIにアクセスするWebアプリケーションを作成し，httpリクエストのGETメソッドで情報を取得できるか確認する

# 本記事の目的
1. Lambdaの基礎的な使い方がわかる．
1. LambdaでHTTPリクエストを送信し，GET通信ができる．

# GET通信とは
```
GETは、HTTPリクエストの「種類（方法）」のひとつです。

GET通信の役割はズバリ、

💬「◯◯のデータちょうだい！」

という データの「読み取り専用のお願い」。

たとえば、天気予報サイトにアクセスするときは、

GET /weather/today
のような感じで、「今日の天気のデータちょうだい！」って言ってます。

```
>ChatGPTより

本記事では，Reactで作成したWebアプリケーションからGETをLambdaに対して要求することで，Lambdaはランダムな値をReactに渡します．

# Lambdaの作成
AWS Lambdaで関数を作成し，「コード」に以下のコードをペーストします．
ランタイムは「Node.js」を選択します．
```javascript index.mjs
export const handler = async () => {
  const randomNumber = Math.floor(Math.random() * 100);
  return {
    statusCode: 200,
    headers: {
      "Access-Control-Allow-Origin": "*",
    },
    body: JSON.stringify({ number: randomNumber }),
  };
};
```
こちらがランダムな値（0~99）を返してくれる関数になります．
「テスト」タブを選択することでテストを実行することができます．
テストを行い，以下のような結果になることを確認してください．
![スクリーンショット 2025-04-19 15.12.56.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/a29c9cdd-e4d6-454e-b8fb-8eb9b4e40bba.png)

今回は60がランダムな値として返ってきました．

# LambdaをAPIで呼び出せるようにする
この関数をローカルでAPIとして呼び出し，使用できる状態にします．
そのために用いるのが`AWS API Gateway`です．
### APIとは
```
**API（エーピーアイ）**は、
**Application Programming Interface（アプリケーション・プログラミング・インターフェース）**の略で、
簡単に言うと、

「ソフトウェア同士が情報をやり取りするための、共通のルールや窓口」

のことです。
```
>ChatGPTより

APIを使用することにより，異なるソフトウェア同士（今回はLambdaとReact）で通信が可能になります．
基本的にAPIはURLの形式で使用され，URLを呼び出すことで異なるソフトウェア同士で通信をします．
`API Gateway`ではこのURLの発行を行うことができます

### API Gatewayの作成

1. APIのタイプを選択する．今回は`HTTP API`を選択します．
1. 画像のようにして，API名と統合する（APIを作成したい）Lambdaを決定します．
![スクリーンショット 2025-04-19 15.21.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/644f4cb0-d4d6-4a7f-a355-26740dcbdd23.png)

1. ルートを設定する．
今回はGET通信なのでメソッドは`GET`を選択し，リソースパスには`/`，統合ターゲットは統合したLambdaを選択します．

（注意：Webページを複数ページで構成する場合，リソースパスに適切なパスを指定してください）

 ![スクリーンショット 2025-04-19 15.32.36.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/ee522ae5-2a5a-4248-a8e4-d546c09c51a9.png)

1. ステージを設定する．
アプリ開発では開発用のステージとリリース用のステージを分けてAPIを作成することが多いですが，今回は練習なのでなんでもいいです．自動デプロイはOFFにしておきましょう．

1. 確認して作成

### CORSの設定をする

#### CORSとは
```
CORS は Cross-Origin Resource Sharing（クロスオリジン・リソース・シェアリング） の略です。

ひと言で言えば：

💬 「違うドメインからのアクセスを許可するかどうかを決める仕組み」

です。

```
> ChatGPTより

CORSにより，指定していないアドレスからのアクセスは拒否されます．これによりアプリケーションをセキュアにできます．

#### CORSの設定
左のタブから「CORS」を選択すると，以下のような画面に遷移します．「設定」からそれぞれの項目に許可するものを**追加**してください．
![スクリーンショット 2025-04-19 16.24.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/0e7b4c91-1748-40cc-a622-4133a5b0a122.png)

##### Access-Control-Allow-Origin
どのオリジン（ドメイン）からのリクエストを許可するか．
`*`を指定することで，誰からのリクエストでも許可するようにできますし，
`localhost://3000`を指定することによって自分のIPからしかアクセスできないようにすることもできます．
今回は`*`もしくは自分のIPアドレスを指定し追加しましょう．

##### Access-Control-Methods
どのHTTPメソッドを許可するか．
今回は`GET`を許可してください．

##### Access-Control-Max-Age
ブラウザがキャッシュしてよい時間（秒単位）です．今回は指定しなくて大丈夫です．

##### Access-Control-Allow-Headers
どのカスタムヘッダーを許可するか．
今回は`*`を許可してください．
`*`は**全て**を意味します．

##### Access-Control-Expose-Headers
クライアント側からアクセスしていいヘッダー．
今回は指定しなくて大丈夫です．

##### Access-Control-Allow-Credemtials
Cookie等の認証情報を含むリクエストを許可するか．
今回は`いいえ`のままで大丈夫です．

最後に**デプロイ**するのを忘れないでください．
デプロイするとLambda側の[設定]->[トリガー]から画像のようにAPIが確認できるはずです．
![スクリーンショット 2025-04-19 16.40.51.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/fb46e2e3-d69b-4525-a64d-8e0b00d09303.png)

このエンドポイントを呼び出すことでランダムな値を取得することができます．
試しにChrome等のブラウザのURLにペーストしてみると，以下のようにランダムな値を取得することができます．
Webサイトを更新するたびに値が変わるのを確認してください．
![スクリーンショット 2025-04-19 16.43.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/4f50623b-b613-4b6d-a4aa-2ba119ec884e.png)
これでLambdaをAPIで呼び出すことができるようになりました．

# 実際にReactでAPIを使用する
好きなReactプロジェクトで新しくファイルを作成し，以下のコードをペーストしてください．
(Reactのディレクトリ構造やルーティングの設定がわからない場合，App.tsxに以下のコードをペーストしてください．)

`LambdaのAPIエンドポイント`はLambdaの[設定]->[トリガー]から確認できます．
```react　*.tsx
import React, { useState } from 'react';

const RandomNumberFetcher: React.FC = () => {
  const [number, setNumber] = useState<number | null>(null);
  const [loading, setLoading] = useState(false);

  const fetchRandomNumber = async () => {
    setLoading(true);
    try {
      const response = await fetch("LambdaのAPIエンドポイント", {
        method: "GET",
      });
      const data = await response.json();
      setNumber(data.number);
    } catch (error) {
      console.error("Error fetching number:", error);
    } finally {
      setLoading(false);
    }
  };

  return (
    <div>
      <button onClick={fetchRandomNumber} disabled={loading}>
        {loading ? "取得中..." : "ランダムな数字を取得"}
      </button>
      {number !== null && <h2>受け取った数字: {number}</h2>}
    </div>
  );
};

export default RandomNumberFetcher;
```

### コードの解説
本記事のメインはLambdaなので，以下に詳細にコメントアウトをつけたコードを添付します．
```react
// ReactとuseStateフックをインポートします。
// useStateは「状態」を管理するために使います。
import React, { useState } from 'react';

// React.FC は「このコンポーネントは関数コンポーネントですよ」という型の指定です。
const RandomNumberFetcher: React.FC = () => {
  // number: ランダムな数字を保持する変数（初期値は null）
  // setNumber: number を更新する関数
  const [number, setNumber] = useState<number | null>(null);

  // loading: 数字を取得中かどうかを表すフラグ（true なら読み込み中）
  // setLoading: loading を更新する関数
  const [loading, setLoading] = useState(false);

  // ランダムな数字を取得する非同期関数
  const fetchRandomNumber = async () => {
    // API呼び出し中であることを示すため、loadingをtrueに設定
    setLoading(true);

    try {
      // Lambda関数のAPIエンドポイントからデータを取得（GETメソッド）
      const response = await fetch("LambdaのAPIエンドポイント", {
        method: "GET",
      });

      // 応答をJSON形式に変換
      const data = await response.json();

      // 取得した数字をnumberステートにセット
      setNumber(data.number);
    } catch (error) {
      // エラーが発生した場合は、コンソールに表示
      console.error("Error fetching number:", error);
    } finally {
      // 処理が完了したので、loadingをfalseに戻す
      setLoading(false);
    }
  };

  // コンポーネントが実際に表示する内容（JSX）
  return (
    <div>
      {/* ボタンを表示。クリックすると fetchRandomNumber 関数が呼ばれる */}
      {/* loadingがtrueの間はボタンを無効にし、「取得中...」と表示する */}
      <button onClick={fetchRandomNumber} disabled={loading}>
        {loading ? "取得中..." : "ランダムな数字を取得"}
      </button>

      {/* number が null でない（＝数字が取得できた）場合に、その数字を表示 */}
      {number !== null && <h2>受け取った数字: {number}</h2>}
    </div>
  );
};

// このコンポーネントを他のファイルから使えるようにエクスポート
export default RandomNumberFetcher;
```

## 動作を確認する
Webサイトを表示し，以下の画像のようなUIが表示されていることを確認してください．
![スクリーンショット 2025-04-20 21.45.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3820079/fd40c30f-a6b3-4e45-bf3b-d31aae9f5735.png)

ボタンを押すたびに表示される数値が変われば成功です．


# おわりに
これでAWS Lambdaを用いたHTTPリクエストによるGET通信ができたはずです．
今回はReactでLambdaを使用しましたが，VueやPythonといった別フレームワーク，言語でも使用可能です．
次回はPOST通信を行い，ローカルから値をLambdaに送信してみます．