【備忘録】RDSに追加したデータをAPIで取得するまで

## 概要
[前回の記事](https://qiita.com/Ryuto_Yuz/items/0fd278845403353139d9)で、RDSにDBを作成してデータを追加しました。

今回は、その追加したデータをLambdaとAPI Gatewayを使って、APIで取得したいと思います。

:::note warn
著者はAWSについての詳しい知識は持っておりません。そのためこの記事には不正確な点があるかもしれません。もし間違いや改善点を発見しましたら、ご指摘いただけると幸いです。
:::

### 動作環境・前提条件
【動作環境】
- OS: M1 macOS Ventura 13.1
- リージョン: 大阪（ap-northeast-3）
- RDS: MySQL 8.0.32

【前提条件】
- AWSのアカウントを作成していること
- [前回の記事](https://qiita.com/Ryuto_Yuz/items/0fd278845403353139d9)でデータを追加していること

## データをAPIで取得するまで
前回以下のようにデータを追加しました。
![スクリーンショット 2023-05-05 10.37.25.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2278050/f7502a61-84f4-a56a-32ee-0fe013391fc0.png)

今回はAPIを使って、これらのデータをJSON形式で取得したいと思います。

具体的な手順は以下の通りです。
1. Lambdaをローカル環境に作る
2. データを取得するコードを書く
3. コードをテストする

順次解説していきます。

### STEP1 Lambdaをローカル環境に作る
最初にLambdaをローカル環境で作成していきます。

まずはDockerとAWS SAM CLIをインストールする必要があります。
具体的な手順はOSによって違うので、詳しくは[以下の記事](https://docs.aws.amazon.com/ja_jp/serverless-application-model/latest/developerguide/install-sam-cli.html)を参考にしてください。
以下はMacの手順です。
```sh
brew install docker
brew tap aws/tap
brew install aws-sam-cli
```

ちなみに僕はHomebrewでDockerをインストールしても、うまくいかなかったので、Desktop版をダウンロードしました。

https://docs.docker.com/desktop/

インストールができたら、以下のコマンドを入力して、Lambda関数を作成します。
``` sh
sam init
```
するといろいろ出てくると思うので、以下のように入力してください。

``` sh
Which template source would you like to use?
	1 - AWS Quick Start Templates
	2 - Custom Template Location
Choice: 1

Choose an AWS Quick Start application template
	1 - Hello World Example
	2 - Multi-step workflow
	3 - Serverless API
	4 - Scheduled task
	5 - Standalone function
	6 - Data processing
	7 - Hello World Example With Powertools
	8 - Infrastructure event management
	9 - Serverless Connector Hello World Example
	10 - Multi-step workflow with Connectors
	11 - Lambda Response Streaming
	12 - Lambda EFS example
	13 - DynamoDB Example
	14 - Machine Learning
Template: 1

Use the most popular runtime and package type? (Python and zip) [y/N]: N

Which runtime would you like to use?
	1 - aot.dotnet7 (provided.al2)
	2 - dotnet6
	3 - dotnet5.0
	4 - dotnetcore3.1
	5 - go1.x
	6 - go (provided.al2)
	7 - graalvm.java11 (provided.al2)
	8 - graalvm.java17 (provided.al2)
	9 - java17
	10 - java11
	11 - java8.al2
	12 - java8
	13 - nodejs18.x
	14 - nodejs16.x
	15 - nodejs14.x
	16 - nodejs12.x
	17 - python3.9
	18 - python3.8
	19 - python3.7
	20 - python3.10
	21 - ruby2.7
	22 - rust (provided.al2)
Runtime: 13

What package type would you like to use?
	1 - Zip
	2 - Image
Package type: 1

Select your starter template
	1 - Hello World Example
	2 - Hello World Example TypeScript
Template: 1

Would you like to enable X-Ray tracing on the function(s) in your application?  [y/N]: y

Project name [sam-app]: UserGetApp

```

`UserGetApp`というフォルダが生成されていればOKです！

最後に、以下のコマンドでビルドしてください。
``` sh
cd UserGetApp
sam build
```

### STEP2 データを取得するコードを書く
ではここからは、MySQLからデータを取得するコードを書いていきます。

まず最初にアプリにMySQLをインストールする必要があります。

アプリ内の`package.json`のあるフォルダに移動してください。（手順通りに進んでいれば、UserGetApp/hello-world/にあるはず！）

移動したら、以下のコマンドを入力してMySQLをダウンロードしてください。
``` sh
npm install mysql2
```

`package.json`を開いて、MySQLがダウンロードできていればOKです。
``` json
  "dependencies": {
    "axios": ">=0.21.1",
    "mysql": "^2.18.1",
    "mysql2": "^2.3.3"
  },
```

ダウンロードができれば、`app.mjs`を開いて以下のコードを入力してください。
``` javascript
import mysql from "mysql2/promise";

const connection = await mysql.createConnection({
    host: 'DBのエンドポイント',
    user: 'ユーザー名',
    password: 'パスワード',
    database: 'sample_database'
});

export const lambdaHandler = async (event, context) => {
    const sql = 'SELECT * FROM User';
    let response = {};
    
    try {
        const [result, field] = await connection.execute(sql);
        
        response = {
            statusCode: 200,
            body: JSON.stringify(result)
        };
    } catch (error) {
        console.log(error);
        response = {
            statusCode: 200,
            body: JSON.stringify(error)
        };
    }
    
    return response;
};

```
DBのエンドポイントやユーザ名などは、ご自身で設定した値を入力してください。

コードを変更したら、再度ビルドして下さい。
``` sh
sam build
```

ビルドが成功したら、以下のようにLambda関数をデプロイします。
``` sh 
sam deploy --guided

Configuring SAM deploy
======================

	Looking for config file [samconfig.toml] :  Found
	Reading default arguments  :  Success

	Setting default arguments for 'sam deploy'
	=========================================
	Stack Name [UserGetApp]: 
	AWS Region [ap-northeast-1]: ap-northeast-3 // ここはご自身の使用しているリージョンで構いません。
	#Shows you resources changes to be deployed and require a 'Y' to initiate deploy
	Confirm changes before deploy [Y/n]: Y
	#SAM needs permission to be able to create roles to connect to the resources in your template
	Allow SAM CLI IAM role creation [Y/n]: Y
	#Preserves the state of previously provisioned resources when an operation fails
	Disable rollback [y/N]: y
	HelloWorldFunction may not have authorization defined, Is this okay? [y/N]: y
	Save arguments to configuration file [Y/n]: Y
	SAM configuration file [samconfig.toml]: 
	SAM configuration environment [default]: 
```

デプロイが成功したらOKです！

### STEP3 コードをテストする
ご自身のコンソールから「Lambda」を選択して、Lambda画面へ移動して下さい。
デプロイが成功していれば、「UserGetApp」が作成されているはずです。
![スクリーンショット 2023-05-10 11.36.53.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2278050/ab613184-03bf-51db-5b82-45dd3f79e3bb.png)


関数詳細画面へ移動したら、画面下の「テスト」タブをクリックし、以下のように設定して下さい。
- テスト名: Test
 ```  json
{
  "key1": "value1",
  "key2": "value2",
  "key3": "value3"
}
```
![スクリーンショット 2023-05-10 11.41.40.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2278050/b73964ce-067e-6426-e373-ac0083962c5b.png)


テストを実行して成功すればOKです。
![スクリーンショット 2023-05-10 11.42.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2278050/d341c3a8-fce7-2c28-d22a-ad110c565106.png)



最後に「設定」タブをタップして、表示されたURLに飛んでみて下さい。
以下のようなJSONが表示されるはずです。
``` json
[
	{
		"id": 1,
		"name": "A",
		"age": 20
	},
	{
		"id": 2,
		"name": "B",
		"age": 30
	},
	{
		"id": 3,
		"name": "C",
		"age": 35
	},
	{
		"id": 4,
		"name": "D",
		"age": 28
	},
	{
		"id": 5,
		"name": "E",
		"age": 40
	}
]
```

コード内のSQL文やURLのクエリを設定すれば、欲しいデータだけを取得することもできます。

## まとめ
最初は完全に理解しようとせず、とりあえず手順だけ覚えて、徐々に理解を深めていきたいと思います。

## 参考にした記事
https://tech-blog.rakus.co.jp/entry/20210309/aws