REST APIでDynamoDBのテーブルを操作

## 概要
REST APIでAWS上のDynamoDBのテーブル操作を行う方法を記載
CURLでAPI GatewayにデプロイしたAPIを叩いてDynamoDBと通信

## 目次
1. REST APIとは
1. DynamoDBのテーブルを作成
1. ロールの作成
1. Lambda関数を作成
1. API GatewayでAPIをデプロイ
1. CURLによる動作確認

## 1. REST APIとは
REST APIは、REST（Representational State Transfer）の原則に基づいて設計されたAPIのことを指し、HTTP通信によって、データの作成/読み取り/更新/削除の機能を実行できます。要求されたリソースに関する情報を提供し、以下の4つのメソッドを使用してリソースの処理方法を記述します。
GET：リソースを取得
POST：リソースを作成
PUT：リソースを更新
DELETE：リソースを削除
また、リソースを様々な形式（HTML/XML/JSON/バイナリ）で表現できるようになっています。

## 2. DynamoDBのテーブルを作成
一連の手順を備忘として記載するので、例えばAWSサービスの細かな説明は本記事では割愛します。

AWSのマネジメントコンソールからDynamoDBを検索する。
1. テーブルの作成を押下
![0DynamoDB１.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/59a5d3a5-c89e-27ad-7cd9-6fa8138e9216.png)

1. テーブル名とパーティションキーを入力
パーティションキーは、データの取得などをするときのプライマリキーとなるもの。例えば、idと入力。
![0DynamoDB２.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/80f0df51-4019-7289-34f7-9230e0bc514a.png)

1. 他はデフォルトでokなので、下部にあるテーブルの作成を押下

これで、DynamoDBにテーブルが作成された。この時、特にカラムなどの定義はしない。あとからPOSTメソッドで定義していく。

> DynamoDB
https://aws.amazon.com/jp/dynamodb/

## 3.　ロールの作成
Lambda関数によるDynamoDBへのアクセス権限を許可するため、IAMロールを作成する。

1. 検索欄からIAMを検索し、ロールを選択。
1. IAMロールの作成を行う
1. 信頼されたエンティティを選択において、信頼されたエンティティタイプは"AWSのサービス"、ユースケースは"Lambda"を選択し、次へ。
1. 許可ポリシーの検索乱で、"amazondynamodbfullaccess"と検索しチェックし、次へ。(Dynamodbへのフルアクセス権限を付与するため)
1. 最後に、ロール名を入力して、ロールを作成を押下

作成したロールに選択したポリシーが紐付けられていることを確認できたらok。

## 4. Lambda関数を作成
１章で紹介したPOST/GET/PUT/DELETEの処理を記述したLambda関数を作成する。

1. Lambda関数を作成を押下し、関数名を入力、ランタイムはPython、デフォルトの実行ロールの変更は、既存のロールを使用するを選択し、既存のロールに3章で作成したロールを選択して関数の作成を押下。
![②-1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/546ec447-5319-56b9-7bc2-62b72342e88b.png)
1. 各CRUDの処理をスクリプトファイルに記述する。
1. デプロイを押下してLambda関数を外部から実行できるようにする。
1. CRUDの処理ごと(POST/GET/PUT/DELETE)にLambda関数を作成するので上記(1〜4)をその数分繰り返す。

スクリプトを記述する際は、pythonからAWS上のリソースを操作するためのライブラリであるboto3をimportして処理を書いていく。
ここまでLambda関数の作成が終わった事になる。

## 5. API GatewayでAPIをデプロイ
API Gatewayで4章で作成したLambda関数をメソッドとして定義し、外部から利用できるようにAPIとしてデプロイする。
1. APIを作成を押下し、APIタイプはREST APIを選択。
1. プロトコルの選択は以下の通りに設定し、API名を入力。
![④API Gateway.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/546545a8-44ed-5538-e8bb-39b706416564.png)
1. サイドバーにあるリソースを選択した状態で、アクションを選択し、リソースの作成を押下。
1. リソース名を入力し、リソースの作成を押下
リソースパスは、：/リソース名　となる。
![⑤players.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/754596/4b67723d-fec2-bd09-cb63-674ad5d60894.png)

1. アクションから、メソッドの作成を選択し、POSTを選択しチェックを押下。
1. Lambda関数の欄に先程作成したLambda関数の名前を入力する。この場合、POSTメソッドを作成しているのでPOSTの処理を記述したLambda関数の名前を入力する。
1. マッピングテンプレートを定義するため、統合リクエストを押下する。
飛んできたリクエストメソッドの情報を後続のLambda関数で処理できるようにフォーマット化する。
1. リクエスト本文のパススルーからマッピングテンプレートの追加を選択して、Content-Typeでapplication/jsonを入力してチェックを押下。（コンテンツの形式を指定している）
1. ページ下部にあるテキストエディタに、POSTメソッドにおける使用するマッピングテンプレートを定義していく。HTTPのリクエストパラメータは、headerとbodyにわかれている。POSTメソッドで送る場合、リクエストパラメータのbodyにデータが格納されて転送される。そのため、bodyを指定する。
1. 保存を押下。（特になにも起きない

> API Gateway WebSocket API のマッピングテンプレートのリファレンスPDF
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-websocket-api-mapping-template-reference.html

最後にアクションから、APIのデプロイで、新しいステージを作成する。ステージによってデプロイを管理する。
POSTメソッドのAPIをデプロイできたら、GET/PUT/DELETEに対しても同様の設定を行いAPIをデプロイする。デプロイしたAPIはURLが発行される。

## 6. 動作確認
CURLを使って、APIを叩いていきます。手軽に HTTPリクエストを試行するってわけです。
試しにPOSTとGETメソッドを叩きます。
まずは、POSTメソッド。-dのあとにPOSTのリクエストを投げるためのパラメータを記述する。また、コマンドの末尾には、デプロイしたAPIのURLを記述する。
```terminal:Post
curl -X POST -H "Content-Type: application/json" -d "パラメータ" APIのURL
```
POSTメソッドは、レスポンスは特にないので実行結果は、nullが出力される。
POSTメソッドで、playersテーブルに対してデータを登録したら、GETメソッドを使って、データを取得してみる。
```terminal:Get
curl -X GET APIのURL
```
上記のコマンドで、テーブルのデータが全て出力される。
指定したidをプライマリキーとするデータのみを取得する場合は、以下になる。この場合、id=1のデータを取得する。
```terminal:Get
curl -X GET APIのURL?id=1
```
実行時に例えばzsh: no matches found:とエラーが出る場合は、特殊文字である?をエスケープさせる必要がある可能性があるので、?の前に\をつける。id=1のレコードのみを引っ張って来れたらok。

一応、PUTとDELETEのCURLコマンドも記載しておく。
```terminal:Put
curl -X PUT -H "Content-Type: application/json" -d "パラメータ" APIのURL
```
```terminal:Delete
curl -X DELETE APIのURL
```
DELETEメソッドもGETメソッド同様、?id=値で、削除したいレコードのidを指定できるが、末尾になにも指定しない場合、テーブル自体を削除することになる。テーブルがない状態でPOSTやGETメソッドを実行するとエラーが返ってくるので注意が必要である。

## おわりに
今回は、REST APIでDynamoDBのテーブル操作を行う方法を記載した。
インターネットを使えればいつでも見返すことができるので備忘録として最高（今更っ