以前S3を使って静的なWebコンテンツを公開できる&JavaScriptが動かせると言う記事を書きました。
triobog.hateblo.jp
このときは公開できるのはあくまで静的なページだけだったのですが、API GatewayとLambdaを使うとなんと動的なコンテンツを作れてしまいます。
参考にしたのは以下のサイトです。と言うか以下のサイトを見れば十分かもしれませんが(汗
AWSは画面や仕様がちょくちょく変わるので、現時点での割と新しい情報になります。
qiita.com
qiita.com
最初に、今回作成するものの簡単な全体像を説明しますと、以下のようになります。
今回は分かりやすいようにGETでパラメータを受け取って、それを表示するような代物を作ります。
API Gatewayでクエリを受け取り、Lambda側にパラメータを渡します。
Lambda側では入力したパラメータをそのままAPI Gateway側に返却して、API GatewayではLambdaから受け取った値をフォーマット(HTML)に埋め込んで表示します。
早速API Gatewayを作成・・・と行きたいところですが、先に後ろ側で動くLambdaを作ります。この後でAPI Gatewayを作成するときに、作成したLambdaを指定します。
メニューからLambdaを選びます。新しく[関数の作成]を選択。
今回は[一から作成]を選びます。ある程度Lambdaが分かってきたら[設計図]や[サーバレスアプリケーションのレポジトリ]を見てみるのが良いかと思われる。と言うか自分も今後そうしようと思っています・・・。
名前は適当に設定。ランタイムは今回自分はPython3.6にしましたが、このへんは使いやすい言語を選べば良いと思います。
ロールは既存のロールから選ぶか、もし無ければ[テンプレートから新しいロールを作成]を選ぶのが無難。その場合、IAMの画面から適切なロールを設定してくれるので素直に従いましょう。
色々と必要な設定はありますが、それはAPI Gatewayの設定が終わってからやることにします。
早速テストをしましょう。
右上の[テスト]ボタンをクリック。
テストイベントの設定画面が開きます。こちらも色々と設定がありますが、とりあえずはこのままでOKとします。
[イベント名]に適当な名前を設定して、[作成]をクリック。
テストイベントのプルダウンに作成されたテストイベントが追加されているので、[テスト]ボタンをクリックすると結果が表示されます。
成功しました。まあ当然ですが。
[詳細]の欄にある内容のjsonの値が返されます。[関数コード]を見ると、入力値にかかわらずこのjsonの値を返すようになっています。
ひとまずLambda側の設定はここまでにして、API Gatewayの設定に行きます。
メニューから[API Gateway]を選択。
[今すぐ始める]を選択します。
最初なのでサンプルAPIの作成に関するダイアログが表示されますが、とりあえず[OK]を押しておきます。
[新しいAPIの作成]のラジオボタンから[新しいAPI]を選択します。
[API名]と[説明]は適当に設定します。まだここの設定はURL等には影響しません。
[エンドポイントタイプ]は今回外部からアクセスできるものを作るつもりなので[エッジ最適化]にしておきます。
[APIの作成]ボタンを押下。
APIができました。まずメソッドを追加しましょう。
[アクション]→[メソッドの作成]を選択。
今回は外部からURLを叩けるよう、GETのメソッドを追加します。
プルダウンから[GET]を選択して、チェックボタンをクリックします(慣れないうちはこれを忘れがち)。
本筋からズレますが、GETメソッドが分からない方は(そんな人はこの記事を読まないかもしれませんが)、以下の記事が参考になるかと思います。
qiita.com
GETのセットアップを行っていきます。
[統合タイプ]に[Lambda関数]を選択し、[Lambda関数]に先程作成したLambda関数を指定します。
[保存]ボタンをクリックして変更を反映させます。
権限についてダイアログで聞かれるので、[OK]をクリック。
GETメソッドの設定画面が出てきました。
ここからAPI Gatewayへのアクセスに従って、順を追って設定していきたいと思います。
まずはメソッドリクエストから。
[認証][リクエストの検証][APIキーの必要性]はデフォルトのままにしておきます。
変更点は[URLクエリ文字列パラメータ]の箇所。ここにクエリを追加していきます。
[クエリ文字列の追加]リンクを押下してクエリ名を入力し、チェックボタンを押せば追加が完了します。
今回は「inputMsg」と言う名前にしたので、これがクエリ名になります。
URLでアクセスする時に、"https://<API GatewayのURL>?inputMsg=xxx"と言う形でパラメータが渡されるようになる想定です。
次に統合リクエスト。
ここで設定するのは一番下の[マッピングテンプレート]の部分。
[リクエスト本文のパススルー]はまだ良くわかっていないので、とりあえず推奨のものにしておきました。
[マッピングテンプレートの追加]を選択して、Content-Typeに"application/json"を追加。
下のテキストボックスにLambdaに渡す値のマッピングを設定して、一番下にある[保存]ボタンをクリック。
今回設定したマッピングは以下の通りとなります。
#set($inputRoot = $input.path('$')) { "inputMsg": "$input.params('inputMsg')" }
そしてLambda。
先程のLambdaの画面に戻り、[関数コード]の内容を書き換えます。
import json def lambda_handler(event, context): if event['inputMsg'] != "": result = "取得した値は「" + event['inputMsg'] + "」です。" else: result = "値を取得できませんでした。" return { "result": result }
こんな感じで。
今回は非常にシンプルな感じで、取得したパラメータを文字列で結合して返します。
API Gatewayに戻って、Lambdaから返された値の処理を設定します。
統合レスポンスの設定。
ここでLambdaから返された値をHTMLに埋め込みます。
<HTML> <HEAD> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <TITLE>Hello API Gateway!!</TITLE> </HEAD> <BODY> <h1>$input.path('$.result')</h1> </BODY> </HTML>
Lambdaからの返却値は"$input.path('$.<受け取りたい変数名>')"で受け取れます。
最後にメソッドレスポンス。
ここはレスポンスタイプのコンテンツタイプをapplication/jsonからtext/htmlに変更します。今回返したいのはHTML形式なので。
ここまでできたらテストをしましょう。
画面中央の[テスト]をクリック。
[クエリ文字列]にテスト用のクエリを設定します。
今回は「inputMsg」と言うクエリ名にしたのでこれを入力して、[テスト]ボタンをクリック。
さて、結果は・・・?
どうやら無事想定通りのHTMLが帰ってきたようです。
ではこれをデプロイして実際にアクセスしてみましょう。
[アクション]→[APIのデプロイ]。
[デプロイされるステージ]は新規なので[新しいステージ]を選択。
[ステージ名]には設定したい値を入力します。これがURLの部分に反映されます。
[デプロイ]ボタンを押下すると、無事APIゲートウェイのデプロイができました。
URLの部分を見ると、最後に先程設定したステージ名が表示されています。
ではURLにアクセスしてみましょう。
URLの後に付けたクエリを取得して、表示できていることが確認できました。
クエリがない場合の例外処理も、Lambdaで設定した通りにできました。
今回は動的なコンテンツが作れるかを確認するために単純にGETパラメータを表示するだけのものを作りましたが、工夫すればもっと色々なことができそうです。
それはまたおいおいやっていきたいと思います。
そんな訳で、今日はこれまで。
それでは、ごきげんよう。