ゼロから作りながら覚えるAPI Gateway環境構築

API Gateway

こんにちは、臼田です。

みなさん、Lambdaしていますか?

Lambdaと合わせてAPI Gatewayを使う場面も何かとあるかと思います。

本ブログでは様々なAPI Gatewayの記事があり、下記のまとめも参考になります。

【まとめ】API Gatewayを学ぶための記事まとめ

しかし、ゼロからAPI Gatewayを構築して、実際に今後APIの実装を行なって行こうとする時に何からやればいいかわからない、ということもあるかと思い今回その手順をまとめようと思いました。

本ブログの趣旨

本稿は以下の内容を意識して作成しました。

  • これからAPI Gatewayを使ってAPIを構築しようとしている人向け
  • API Gatewayと、連携するLambdaのモック、それに付随したIAMを作成する
  • とりあえずAPI Gatewayの環境を作成し、APIの実装やバックエンドのロジックに取り掛かれるようにする
  • API Gatewayの用語は要所で解説

構築手順

大まかな流れ

以下のような流れで説明します。

  • Lambdaの作成
    • 途中でIAM Roleの作成
  • API Gatewayの作成
    • リソースの追加
    • Lambdaとの連係
    • APIキー認証の追加
    • デプロイ
    • ステージング

Lambdaの作成

API Gatewayを作成する場合、API Gatewayのバックエンドを指定する必要があります。

その為、バックエンドをLambdaとする場合にはまずAPI Gatewayからのリクエストを受けるLambdaが必要になります。

今回はとりあえずAPI Gatewayからのデータを受け取り、そのまま返すLambdaをPython3で用意します。

マネジメントコンソールからLambdaのページにアクセスし、「関数の作成」を押します。

001_lambda

今回は予めAWS側で用意されているblueprint(テンプレート)を利用します。

フィルターに「hello」と入力してEnterして、「hello-world-python3」を選択します。

002_lambda

「基本的な情報」では、名前を適当に入力し、ロールは「テンプレートから新しいロールを作成」を選択します。

ロール名も適当に選択した後、今回はポリシーテンプレートを空欄とします。

こちらは空欄でも、最低限Lambdaに必要なアクセス権限は自動的に作成されます。

なお、この後SQSやAWS Batch等別のサービスとの連係を行う予定があれば、ポリシーテンプレートでそれらを選択してもいいです。

003_lambda

下にスクロールし、「関数の作成」を押します。

005_lambda

Lambdaが作成されたら関数のコードを確認します。

eventがリクエスト元から受け取る内容ですが、「hello-world-python3」では3つの値をprint(CloudWatchに記録される)してkey1をreturnするようになっています。

006_lambda

 

今回はとりあえず入力値をそのまま出力すればいいので下記のように変更します。

import json


def lambda_handler(event, context):
    print("Received event: " + json.dumps(event, indent=2))
    return event

すっきりしました。

eventを全てprintし、eventをそのままreturnします。

変更したら、上方にある「保存してテスト」を押します。

007_lambda

イベント名を適当に入力し、下にスクロールして「作成」を押します。

008_lambda

009_lambda

テストを実行します。

010_lambda

テストが成功しました。

実行結果の「詳細」をクリックすると内容が確認できます。

最初にあるのがreturnの内容で、右下のログ出力に含まれるのがprintにてCloudWatchログに出力された内容になります。

011_lambda

以上で、Lambdaの作成と付随するIAM Roleの作成は完了です。

API Gatewayの作成

続けてAPI Gatewayも作成します。

API Gatewayのページへ移動し、「今すぐ始める」を押します。

012_apig

「新しいAPI」を選択し、API名を適当に入力して「APIの作成」を押します。

013_apig

APIが作成されました。

初期状態では何もない状態になります。

014_apig

ここで少し、「リソース」と「メソッド」について説明します。

リソースとは

簡単に説明するとAPIのパスです。

デフォルトでは「/」のみなので、APIのエンドポイントがhttps://api.example.comだったとすると、この直下へのアクセスとなります。

ここからusersリソースを追加し、例えばhttps://api.example.com/usersのようにすることが可能です。

リソース配下にリソースを配置してパスを深くすることもできます。

リソースの中にメソッドを定義していきます。

メソッドとは

リソースに対するアクションで、HTTPのメソッド「GET, POST」等と連携します。

例えばusersリソースのPOSTメソッドを作成すると、https://api.example.com/usersに対するPOSTリクエストがあった際の処理を定義できます。

処理はLambdaへのリクエストはもちろんのこと、API Gatewayでの認証やリクエストbodyの加工などを挟んで、Lambda以外にも別のHTTPエンドポイント等への転送も定義できます。

メソッドは一つのリソースに対して複数定義することができ、例えばusersリソースのGETメソッドを追加してユーザの追加と参照を一つのリソースで実装することもできます。

この際、API Gatewayでメソッドの設定を分けているので別々のLambdaで処理することもできます。

リソースとメソッドの作成

それでは、リソースとメソッドを作成していきます。

デフォルトのリソース「/」を選択した状態で「アクション -> リソースの作成」を押します。

015_apig

リソース名を適当に入力し、「リソースの作成」を押します。自動でリソースパスも入力されます。

016_apig

リソースが作成されたので、続けてメソッドも作成します。

作成したリソースを選択して「アクション -> メソッドの作成」を押します。

017_apig

HTTPメソッドの選択となるので、POSTを選択してチェックボタンを押します。

018_apig

セットアップが出てくるので統合タイプ「Lambda関数」とし、LambdaリージョンとLambda関数を適切に入力して「保存」を押します。

関数名は、補完してくれるのでそれをクリックすれば大丈夫です。

020_apig

API GatewayにLambdaを呼び出す権限を自動で追加してくれるので「OK」を押します。

021_apig

これでリソースとメソッドが作成できました。

API Gateway内部でのテストを行うため「テスト」を押してテストしてみます。

022_test

ページ下方のリクエスト本文に適当なjson(今回は{"test":1})を入力して「テスト」を押します。

023_test

レスポンスとして、リクエストした内容がそのまま返ってきていることが確認できれば、先ほど作成したLambdaで実行されていることが確認できています。

024_test

これでAPI Gateway内部でのテストが完了しました。

しかし、現状ではこのAPI Gatewayは外部からアクセス出来る状態ではありません。

APIのデプロイ

作成したAPIをデプロイして、外部からアクセスできるようにしていきます。

ここでまた少し用語の解説を行います。

デプロイ

APIを外部に公開する作業。

初回デプロイ時にはそのAPIのエンドポイント(URL)が生成されます。

デプロイ時にはその段階のリソース・メソッド等の設定を反映したバージョンが作成され、以後デプロイするたびにバージョンが増えます。デプロイされたバージョンの内容を変更することはできません。

エンドポイントに来るリクエストをどのバージョンで処理するかはステージで関連付けます。

ステージ

エンドポイントとデプロイバージョンを紐付けるエイリアスです。

例えば、devprodという2つのステージを用意しておき、devに最新バージョンのデプロイを行い、prodは安定したバージョンのままにしておき、開発用とエンドユーザに提示するエンドポイントを分けることができます。

エンドポイントはそれぞれ、https://api.example.com/devhttps://api.example.com/prodとなります。

リソースは実質ステージの下のリンクとなります。例えばdevステージのusersリソースへのアクセスはhttps://api.example.com/dev/usersとなります。

ステージで利用するデプロイバージョンは任意のタイミングで変更が可能なので、ロールバックも簡単に可能です。

 

それではデプロイに移りたいのですが、API GatewayでAPIをデプロイするとパブリックに公開されます。そのままでは誰でもアクセスできてしまいあまり好ましい状態ではありません。

先にAPIキーを作成し、APIリクエスト時に認証を行うようにします。

メニューから「APIキー」へ移動し「アクション -> APIキーの作成」を押します。

025_api

名前を適当に入力し「保存」します。APIキーは「自動生成」で問題ありません。

026_key

作成されるとAPIキーが隠れているので「表示」を押してAPIキーを控えます。

027_key

続いて作成したAPIキーをメソッドに割り当てます。

先ほど作成したメソッドを開いて「メソッドリクエスト」を選択します。

028_api

「APIキーの必要性」で鉛筆アイコンを押して編集します。デフォルトのfalseからtrueに変更してチェックボタンをクリックします。

029_api

忘れずにチェックボタンを押してtrueに変更されたことを確認したら、「アクション -> APIのデプロイ」でデプロイします。

030_deploy

デプロイされるステージに「新しいステージ」を選択してステージ名を入力し、「デプロイ」を押します。説明は任意で問題ありません。

031_deploy

完了するとステージが作成されるとともに、エンドポイントも作成されています。

032_deploy

さて、この状態でAPIにアクセスできるようになったかと思いきや、APIキーを利用した認証にはもうワンステップ必要です。

使用量プランの設定

ステージで利用できるAPIキーを紐付ける必要があり、これは使用量プランで設定できます。

使用量プラン

使用量プランは個々のAPIキーに対してスロットリングやクォータ制限等を行うことができます。

合わせて、APIキーを利用した認証も行います。

APIキー毎にリクエスト数の上限設定等を行えることから、ユーザ毎契約状況に合わせてプランを変更する、等の利用方法が有ります。

 

それでは使用量プランのページへ移動し「作成」を押します。

033_usage

名前を適当に入力します。今回は認証のみのため、「スロットリング」「クォータ」についてはチェックを外して「次へ」を押します。

034_plan

使用量プランとステージを紐付けます。「APIステージの追加」からAPIとステージを選択してチェックボタンを押し、「次へ」を押します。

035_plan

続いてAPIキーを紐付けます。「APIキーを使用量プランに追加」からAPIキーを選択してチェックボタンを押し、「完了」を押します。

036_plan

これでAPIキーも紐付き、利用できる状態となりました。

APIの動作確認

それでは外部からのアクセスを確認してみます。

curlで確認する場合には、-dオプションでPOSTのデータを指定でき、-Hでヘッダーを追加できます。

APIキーを送るフォーマットはx-api-key:<api_key>となります。

APIキーの有無でそれぞれ下記のような実行結果となります。

# APIキーがない場合
$ curl -d '{"test":1}' https://api.example.com/dev/test
{"message":"Forbidden"}

# APIキーを指定した場合
$ curl -d '{"test":1}' -H 'x-api-key:xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' https://api.example.com/dev/test
{"test": 1}

以上で、実環境に必要な認証の設定も含む手順が確認できたかと思います。

この後やること

さて、一通りの手順を説明しましたが、今後実際に開発を行っていく場合には下記のような内容も行なっていく必要があります。

  • prodステージの追加
  • Lambdaの処理の追加
  • リソースの追加
  • リクエスト・レスポンスのマッピング
  • カスタムドメインの利用
  • などなど

冒頭でも貼りましたが、下記のまとめ等も参考によい開発ライフを!

【まとめ】API Gatewayを学ぶための記事まとめ