AWS API GatewayのHTTP APIでLambdaを呼び出す

#はじめに
AWSのLambda関数をわりと新しく出来たばかりらしいAPI GatewayのHTTP APIでセットアップしてみました。

当初、lineのmessenger APIを用いて、line botを作りたいと思っていたのですが、

途中で、

AWSのLambdaとAPI Gateway？
REST API ??
HTTP API ??

分からん！

とパニック状態の私を見かねて助けてくれた仏のような友人の手を借りて、

とりあえず、動作確認が何とか成功しました。

当方、プログラミングもAWSも初心者中の初心者であるため、前提知識がかなり乏しいですが、今回分からないなりにそのプロセスをまとめてみます。

#Lambda関数を作成
まず、最初にLambda関数を作成していきます。

![スクリーンショット 2019-12-20 20.28.41.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/278e453b-beb8-edb3-21f8-dd22dbb16af7.png)


↑AWS Lambdaのサービスのダッシュボードを開いたら、オレンジ色の関数の作成というボタンをクリックします。

![スクリーンショット 2019-12-20 20.25.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/c5d8216b-a7f9-5b19-584a-7311236106a0.png)

↑あるいは、関数のページにも関数の作成というリンクがあるので、こちらから飛んでもOKです。

![スクリーンショット 2019-12-20 20.38.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/7b56b788-ceac-d91b-3199-5ef3ea0b8271.png)


↑関数の作成ページの「一から作成」を選択し、適当な関数名とランタイムには関数を入れる言語を選択します。今回はテストのみであるため、関数名は「HelloLambda」、ランタイムには「Ruby 2.5」を選択します。

![スクリーンショット 2019-12-20 20.41.44.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/f4896998-d77c-85f8-b0ba-471e69e9c2cc.png)

↑また、実行ロールについては、初期設定の「基本的なLambdaアクセス権限で新しいロールを作成」としておき、関数の作成をクリックします。

![スクリーンショット 2019-12-20 20.44.11.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/ec26f54e-f082-18a8-56cf-ac7e7967f309.png)

↑するとこのような画面が出てきて、その下には、

![スクリーンショット 2019-12-20 20.45.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/438aa18e-7699-23c9-fe8e-2f3be23f3b90.png)

関数コードがデフォルトで入力されております。今回はこのままのコードでテストします。

また、先ほどの画面の上部の緑色の帯に書いてあるように、テストを実行します。

![スクリーンショット 2019-12-20 20.47.31.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/7cc22504-ecd8-13c9-efd3-f8b075e9c14d.png)

![スクリーンショット 2019-12-20 20.51.07.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/8abcc0f2-e2e0-0ff0-91a0-d801bd6ac36d.png)

↑そうするとこのようにテストイベントの設定という画面が出てくるため、適当なイベント名を入力し、右下の作成ボタンをクリックします。

イベント作成後に再びテストを実行すると、

![スクリーンショット 2019-12-20 20.55.10.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/0f8994b7-8715-c16d-eda8-8a23ab06aa60.png)

実行結果：成功、となりcloud watchログにも反映されます。

所要時間に16.92ms、課金期間に100msと出ておりますが、

Lambdaの場合、~~100ミリ秒単位で課金され、今回のテストは16.92ミリ秒しかかかっておりませんので、もちろん課金はされません。~~
勘違いしてまして、100ミリ秒単位で切り上げでした!
そのため、今回だと100ミリ秒分課金されます。

ただし、Lambdaには無料利用枠があります。

[AWS Lambda 料金](https://aws.amazon.com/jp/lambda/pricing/)

>AWS Lambda の無料利用枠には、1 か月に 1,000,000 件の無料リクエストおよび 400,000 GB-秒のコンピューティング時間が含まれます。

なので、今回は無料利用枠の範疇ですので、料金は発生していないはず...


ちなみに、cloud watchログのリンクに飛ぶと、

![スクリーンショット 2019-12-20 21.03.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/27675e46-9e67-63bc-26e2-896cfbb628d9.png)

↑このように、ログストリームに先ほどテストしたイベント情報が見られます。

ひとまず、これでHelloLambda関数が作成されました。

最初の関数一覧のページに戻ってみると、

![スクリーンショット 2019-12-20 21.00.42.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/424d2138-c7b9-081f-c929-899b9729475c.png)

先ほどはなかった、HelloLambda関数が一覧に出てきますね。

#API GatewayでHTTP APIの作成
それでは、API GatewayでHTTP APIを作成します。

その前に...

![スクリーンショット 2019-12-20 21.09.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/18443079-99cc-0720-5515-cccb169063e0.png)

↑赤枠で囲っているところに注目して欲しいのですが、

リージョンを必ず**東京**にしてください。

正直原因は完全には分かっていないのですが、恐らく、これが原因で後々ハマってしまいました...

今はとりあえず、正しい方法で進めていきます。

先ほどの画面の右上にある「APIを作成」のタブをクリックします。

![スクリーンショット 2019-12-20 21.26.16.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/74be31d8-dcb9-6f4f-5576-407805e951c3.png)

↑すると、この4つのAPIタイプが出てきます。

最初、上記のサイトにあるように、REST API(privateではない方)で進めていたのですが、

とある神より、HTTP APIがめっちゃ便利でお手軽だよと天の声を頂き、

RESTタイプを一旦脇にそっと置いて、

HTTPタイプなるものをチョイスしました。

では、具体的に何が違うのか。

以下のアマゾンの説明を見てみます。

[Amazon API Gateway](https://aws.amazon.com/jp/api-gateway/)

>API オプション

>HTTP API
HTTP API を使用すれば、API プロキシ機能を必要とする高性能 RESTful API を API 管理機能なしで構築できます。HTTP API はサーバーレスアプリケーションと HTTP バックエンド向けに最適化されており、REST API と比較して最大 70％ のコスト削減を実現します。

>REST API
REST API は、単一のソリューションで API プロキシ機能と管理機能を同時に必要とするワークロードに使用します。API 管理機能には、API キー、API の公開、API の収益化による使用量クォータの追跡と適用が含まれます。

>WEBSOCKET API
WebSocket API を使用すれば、チャットアプリケーション、ストリーミングダッシュボードといったリアルタイム双方向通信アプリケーションを構築できます。API Gateway は、バックエンドサービスとクライアント間のメッセージ転送を処理するために永続的な接続を維持します。

ということである。うーん...

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/b86b2eb0-f7a7-9012-6376-9789c39ceee4.png)

HTTP APIに関しては、以下のサイトにもう少し分かりやすく書いてありました。

[【速報】料金 / 開発コストを大幅削減！Amazon API Gatewayの新しい料金モデル「HTTP API」が発表されました！ #reinvent](https://dev.classmethod.jp/cloud/aws/api-gw-http-api/)

要するに、HTTP APIはシンプルにAPIが作成できて、変更も楽ちん、しかも安い！！

ざっくりこんなイメージで理解しました。

大きな違いとしては、HTTP APIは、

- 自動デプロイ
- デフォルトステージ

があるが、REST APIは手動でデプロイしなければならないのと、ステージングを自分でやらなければならない。

そして、REST APIにはオーソライザーに、

- Lambdaオーソライザー
- IAMアクセス権限
- cognitoオーソライザー

とか色々使えるのに、

HTTP APIは、

- JWTオーソライザー

一つしか使えないとか制限があるようです。

つまり、HTTP APIは多機能を捨てて、Lambda関数に特化したシンプルなAPIで、

それに付随してコストがかなり安くなったよーと。

まぁ、まだまだ分からないことだらけですが、ひとまず話が逸れてしまったのでAPI作成の続きを。

とりあえず、今回はHTTP API(Beta)で構築してみます。

![スクリーンショット 2019-12-20 22.08.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/cd1a16a2-a9fa-b014-79b1-943fe20c79f4.png)

↑HTTP APIのブロックで構築をすると、この画面が出てくるので、

統合タイプのタブをプルダウンしLambdaを選択し、さっき作った"HelloLmbda"関数を選択します。

また、適当なAPI名を入力します。

ここではとりあえず、HelloLambdaという名前にして、次に進みます。

![スクリーンショット 2019-12-20 22.19.58.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/c89a4be5-8b4b-9df7-7c05-659d4ca679fe.png)

すると、ルートの設定画面が出てきます。

このルートの設定というのが、RESTに比べてかなりシンプルになっているということで、

エンドポイントから統合バックエンド(ここではLambda)までが、

ここに書いてある、

リソースから統合ターゲットまでの２点で結ばれているということのようです。

エンドポイントやリソース、統合については、下のAWSブログ記事に説明がありました。

[API Gateway のアップデート – API 開発を簡素化する新機能](https://aws.amazon.com/jp/blogs/news/api-gateway-update-new-features-simplify-api-development/)

ちなみに、REST APIで構築すると、

![スクリーンショット 2019-12-20 22.39.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/290135c2-4e8f-dafd-588a-5591ba0e2b84.png)

↑こんな感じで色々と自分でリソースやメソッドを作ったり、

ステージがデフォルトのものがなかったり、

![スクリーンショット 2019-12-20 22.39.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/ce74cb24-38e4-2a05-7f28-d18dc6c62280.png)

↑ルートがこんな感じで長かったりします。

ひとまずRESTの方は置いといて、HTTPのステージ定義ですが、

![スクリーンショット 2019-12-20 22.45.21.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/08e7eaa3-efc2-0926-9202-4b18fa33d058.png)

このように、デフォルトで用意されており、しかも自動デプロイまで用意されています。

ステージを追加したり、自動デプロイにしたくなければ機能をoffにすることもできます。

![スクリーンショット 2019-12-20 22.48.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/54ad1244-b32b-50a0-0a37-1488fb14c1cf.png)

この画面が出たら作成を押せば、簡単にAPIが出来てしまいます。

![スクリーンショット 2019-12-20 22.50.15.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/554575/17d57883-04c1-0eee-2e34-bc0ec9c62330.png)

作成したら、この画面のURLをコピーし、

ターミナルで、

```terminal
curl -X POST -H 'Content-Type:application/json' your URL 
```
your URLの部分にさっきコピーしたURLを貼り付けて、最後に、/api名を入れてください。

例えば先ほどの私の例で作成したAPIのURLでHelloLambda関数を呼び出してみると、

```terminal
"Hello from Lambda!"
```

と返ってきました。

Lambda関数にデフォルトで定義されているアクションですね。

これが出れば呼び出し成功ということになります。

#最後に
最後に私が今回これに成功する前にハマってしまった話をしますと、

リージョンの話をチラッとしましたが、

私はLambdaもAPI Gateway何故か最初のリージョンをオハイオで登録してしまっていて、

そのままRESTで構築して、関数を呼び出したところ、

```terminal
{"message":"Not Found"}
```

というエラーが出てしまいました。

その後、HTTPでやっても出てきてしまい、

最終的には、リージョンを東京に変えて作り直したにも関わらず、

何故か同じエラーが発生。

お手上げ状態だったのですが、

もう一度、LambdaもAPI Gatewayも作成し直したら、成功しました。

原因はいまだに不明ですが、リージョンが原因の一つになっているのではないかと推測しています。

オハイオがサポートされていないのかな？と思ったのですが、

調べてみたら、どうやらオハイオでもサポートはされているみたいです。

[Amazon API Gateway、HTTP API を使用して、より高速で、安価で、よりシンプルな API を提供 (プレビュー)](https://aws.amazon.com/jp/about-aws/whats-new/2019/12/amazon-api-gateway-offers-faster-cheaper-simpler-apis-using-http-apis-preview/)

>HTTP API (プレビュー) は、北バージニア (us-east-1)、オハイオ (us-east-2)、北カリフォルニア (us-west-1)、オレゴン (us-west-2)、アイルランド (eu-west-1)、フランクフルト (eu-central-1)、東京 (ap-northeast-1)、シドニー (ap-southeast-2) の 8 つの AWS リージョンでご利用いただけます。API Gateway が利用できる場所を確認するには、AWS リージョン表をご覧ください。

ただ、リージョンが遠すぎると不具合が起こるとか怒らないとか...

あと、もう一つのリージョンを東京に変えても起こったエラーについては、完全にお手上げです...

どなたか、このあたりに詳しい方教えていただきたい...


てなわけで、次回は今度こそLine bot作成に取りかかりたいと思います！