API GatewayとJSONサーバーで動的htmlレンダリングしてみた。
AWSのAPI GatewayとDynamoDBとLambdaでサービス構築してみたかった動機があったので、今回はAPI Gatewayを触ってみた。
- 特定URLにWebブラウザでアクセスする
- API GatewayがJSONデータを取得して、htmlにレンダリングして表示する
というシンプルな構造です。
今回はやらないが、API Gatewayは統合リクエストなどの機能を使えばLambdaを挟まなくてもDynamoDBにアクセスできます。なので、 /1
にアクセスするとDynamoDBのあるテーブルの id 1
にアクセスして必要なデータをJSON形式で取得して、そのデータをAPIGatewayの統合レスポンスでhtmlにマッピングして返す、みたいな簡単なWEBアプリケーションが作れます。その触りだけ書いて行きます。
やりかた
REST APIとかで作る。
![スクリーンショット 2020-05-14 5.12.04.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F23289be8-6913-69d6-4885-d6a002c96131.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=2cd6b00a95f37fc9418ad90b1aac0fb1)
こんな感じで適当に作り
![スクリーンショット 2020-05-14 5.12.37.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2Faeec6490-00d4-0d9e-84b2-dd9b7e64e88a.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=8f4dacec16f7424f7fdb7f60bdbabe07)
GETメソッドを追加する
![スクリーンショット 2020-05-14 5.13.08.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F8c27c3f5-9bc6-e880-15b6-304e950ed60a.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=ac389a2ba5b27129bb9bc6adcfd54e49)
エンドポイントに https://jsondata.okiba.me/v1/json/PiWpM200513171710 みたいなJSONを返してくれるURLをいれる。Lambdaとかに接続させてもいいがその場合は AWSサービス
を選びゴニョゴニョしてください。後ほど書きますがMockだと、統合レスポンスでマッピングできなくてハマります。
今回の帰ってくるデータはこれ
{
"statusCode": 200,
"body": [
{
"id": 1,
"name": "JavaScript",
"tel": "08000000000"
},
{
"id": 2,
"name": "Object",
"tel": "09000000000"
},
{
"id": 3,
"name": "Node",
"tel": "07000000000"
}
]
}
![スクリーンショット 2020-05-14 5.13.47.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F6a400bcb-1976-d446-8726-600cf2db5e45.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=f331b304ae46cae1d7d55a9c0ce81536)
次はここの メソッドレスポンス
と 統合レスポンス
をいじる。
![スクリーンショット 2020-05-14 5.44.49.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2Fe0ac991c-6e4f-ede3-0cc2-a296dafa179d.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=827b28d91245fd1b48102a918679659f)
メソッドレスポンスで 200
のステータスで text/html
がブラウザに帰るように設定する。
このあたりの application/json
を text/html
に変えたらおk。
![スクリーンショット 2020-05-14 5.48.26.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2Ff36d443e-233f-5b3d-7571-20f8fdc23a5d.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=81ef8cbab46c1d0e5ada1247ea663056)
次は統合レスポンスですが、これもこのあたりの application/json
を text/html
に変えたらおk。
https://jsondata.okiba.me/v1/json/PiWpM200513171710 が200を返したときの処理しか書いてないが一旦これでOK
![スクリーンショット 2020-05-14 5.49.48.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F16c2a02a-88b3-a1b2-b8a1-7e86e9de90cd.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=33d5b88a7f4d8e0e19b7dea869a4f388)
#set($inputRoot = $input.path('$.body'))
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link
rel="stylesheet"
href="https://cdn.jsdelivr.net/gh/kognise/water.css@latest/dist/light.min.css"
/>
<title>API Gateway</title>
</head>
<body>
<h1>Qiitaテスト</h1>
<table border="1">
<tr>
<td>id</td>
<td>name</td>
<td>tel</td>
</tr>
#foreach($elem in $inputRoot)
<tr>
<td>$elem.id</td>
<td>$elem.name</td>
<td>$elem.tel</td>
</tr>
#end
</table>
</body>
</html>
マッピングはVTLという名前のテンプレートエンジン?
https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/api-gateway-mapping-template-reference.html
#foreach($elem in $inputRoot)
<tr>
<td>$elem.id</td>
<td>$elem.name</td>
<td>$elem.tel</td>
</tr>
#end
で、一個前の画面に戻っての テスト⚡
![スクリーンショット 2020-05-14 5.44.49.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F8edbe649-22a9-9228-30ab-d05026c1fe62.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=1f8244be59f3a6fca98ab5ceaeedbf02)
テストとかぽちぽちしてると、ちゃんとhtmlが帰ってくれるならおk。
![スクリーンショット 2020-05-14 5.55.08.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F97226ca6-ed96-28eb-fbc1-334104ecd5c2.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=5dc23304717820f2c9e0e15d9e9069d2)
APIのデプロイして、誰でもアクセスできるようにして、ステージ名は適当に develop
とか stage
とかでいいと思う。
![スクリーンショット 2020-05-14 5.56.01.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2Fdd22394f-cbdf-fc77-384a-60d15e7a4483.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=5e29550b89a8e93fbf144ec69b49cf77)
みたいなURLが発行されて完了です。
![スクリーンショット 2020-05-14 5.57.52.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2Fa7cefd4c-6739-8bc6-c16a-67f204d41932.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=f8d12610c362dce38ed56e22effa7de0)
Mockを統合レスポンスで使おうとしてハマった話
![スクリーンショット 2020-05-14 2.07.22.png](https://qiita-user-contents.imgix.net/https%3A%2F%2Fqiita-image-store.s3.ap-northeast-1.amazonaws.com%2F0%2F112929%2F67207d16-b267-375e-aaed-9b88b3d5e530.png?ixlib=rb-4.0.0&auto=format&gif-q=60&q=75&s=6dc12c2d268c5eb0a9499408bcc8a85d)
絵でいうとここが $input.json('$')
が使えなかったので2週間くらいハマってました(途中でこころ折れたりしながらの二週間)
スタック・オーバーフローに 書いてました。
以前 JSONを返す無料APIを3分で作る方法 を書きましたが、今回は https://jsondata.okiba.me/ さんを使わせてもらいました。リクエストを噛まさずにAWSサービス内で完結させようと思ってのMOCKでしたが見事にハマりました。