記事について
Amazon API Gatewayの基本情報まとめ
Amazon API Gatewayの位置づけについて
さまざまな機能、処理をWeb APIとして提供
実際に処理を行うバックエンドとしてはLambda関数、各種AWSサービス、インターネット経由で呼び出し可能なURL+メソッド等
Amazon API Gatewayの概要について
APIの種類
API作成時に以下2つから選択
REST
扱うリソースをURIとして定義し、それらをHTTPメソッド(PUT, GET, POST, DELETE, ... )の表現で操作
主なHTTPメソッド
- GET : 取得
- POST : 追加
- PUT : 更新
- DELETE : 削除
WebSocket
HTTPの上で、クライアントとサーバー間の双⽅向通信を実現するための通信仕様
1つのコネクション上で継続的なデータ送受信を行う(1通信毎にWebSocketは切断しない)
エンドポイントタイプ
APIを使用するクライアントの場所に応じて決定
API作成時に以下3つから選択
エッジ最適化
一旦CloudFrontにルーティング
APIクライアントが地理的に分散している場合に最適
リージョン
リージョンに直接ルーティング
APIクライアントが同じリージョンに固まっている場合に最適
クライアントが同じリージョンの場合にレイテンシ削減に有効
APIを作成したリージョンにAPIがデプロイされる
プライベート
インターネットからのアクセス不可
デプロイとステージ
APIはステージにデプロイすることで呼び出し可能になる
ステージ
デプロイされる環境
製品向けのデプロイ環境をprod
、開発向けのデプロイ環境をdev
等で分けることが可能
ステージ名はURLの一部として使用される、以下ステージ名をprod
にした場合の例
https://<api-id>.execute-api.<region-id>.amazonaws.com/prod/
API作成方式
-
手動作成
-
既存APIのクローン
-
API仕様を記載したSwaggerファイル(JSON, YAML)のインポート
料金
API Gateway
条件:REST API、東京リージョン、キャッシュなし
リクエスト数 (月間) | 価格 (100万 APIコールあたり) |
---|---|
最初の 3 億 3,300 万 | 4.25 USD |
次の 6 億 6,700 万 | 3.53 USD |
次の 190 億 | 3.00 USD |
200 億以上 | 1.91 USD |
月に1万回APIコールした場合、
4.25 USD / 100 = 0.0425 USD
データ転送
インバウンドデータ転送は無料
アウトバウンドデータ転送が発生する場合は別途料金が発生
基本的に1GB/月あたり0.9 USD
API設定(REST)について
「/」を最上位としてツリー構造で「リソース」を定義する
「/」リソース配下にリソースを複数構成可能、配下のリソース名はURLの一部になる
"{}"でパスパラメータを指定可能
各リソースに受け付けるHTTPメソッド(GET, PUT, POST, DELETE...)を指定、複数指定可能
HTTPメソッドによって呼び出される処理を区別可能、区別したくない場合は"ANY"を選択
API例
用途:デバイスの設定取得、更新
API名:DeviceSettingsOperations
URI | メソッド | |
---|---|---|
/ | GET | 全デバイスの設定取得 |
/{deviceId} | GET | 指定したIDのデバイス設定取得 |
/{deviceId} | PUT | 指定したIDのデバイス設定更新 |
メソッド設定
リソースに設定した各メソッドに対して、
一連のフロー(クライアントからのリクエスト → バックエンドでの処理 → クライアントへのレスポンス)を設定する
以下のようにメソッドリクエスト、統合リクエスト、統合レスポンス、メソッドレスポンスの設定を行う
メソッドリクエスト
クライアントからのリクエスト受付に関する設定
以下のような設定を行う
- メソッドをコールするための認証(権限を持ったIAMユーザのみコール可能等)
- 受け付けるクエリパラメータ
- 必須とするHTTPヘッダ
※パスパラメータ:一意のリソース特定に使用するパラメータ、ID等
※クエリパラメータ:省略可能なパラメータ
統合リクエスト
バックエンドへのリクエストに関する設定
以下のような設定を行う
- リクエストの変換
- バックエンドの種類(Lambda, AWSサービス, HTTP, Mock, VPCリンク)
統合レスポンス
バックエンドからのレスポンスに関する設定
レスポンス内容の変換等
メソッドレスポンス
リクエストに対する最終的なAPI Gatewayとしてのレスポンスに関する設定
レスポンス内のステータスコードや、レスポンスヘッダ等の設定
プロキシ統合の使用(リクエスト、レスポンスの変換を必要としない場合)
リクエスト、レスポンスの変換を必要としない場合、プロキシ統合を使用すると、設定項目を大幅に減らすことが可能
バックエンドがLambda関数の場合、以下のようにLambdaプロキシ統合の使用にチェックを入れる
Lambdaプロキシ統合を使用した場合、
LambdaにInputされるデータ(Lambda関数のパラメータeventに入る値)が決まった形式になり、
LambdaからOutputするデータも決まった形式する必要がある
{
"resource": "Resource path",
"path": "Path parameter",
"httpMethod": "Incoming request's method name"
"headers": {String containing incoming request headers}
"multiValueHeaders": {List of strings containing incoming request headers}
"queryStringParameters": {query string parameters }
"multiValueQueryStringParameters": {List of query string parameters}
"pathParameters": {path parameters}
"stageVariables": {Applicable stage variables}
"requestContext": {Request context, including authorizer-returned key-value pairs}
"body": "A JSON string of the request payload."
"isBase64Encoded": "A boolean flag to indicate if the applicable request payload is Base64-encoded"
}
{
"isBase64Encoded": true|false,
"statusCode": httpStatusCode,
"headers": { "headerName": "headerValue", ... },
"multiValueHeaders": { "headerName": ["headerValue", "headerValue2", ...], ... },
"body": "..."
}
実際のAPI作成手順について
前提条件
API設定
- APIタイプ:REST API
- エンドポイントタイプ:リージョン
作成API
API名:DeviceSettingsOperations
URI | メソッド | |
---|---|---|
/ | GET | 全デバイスの設定取得 |
/{deviceId} | GET | 指定したIDのデバイス設定取得 |
/{deviceId} | PUT | 指定したIDのデバイス設定更新 |
メソッドリクエスト設定
- APIコール時の認証にAWS_IAMを使用
統合リクエスト設定
- バックエンドタイプとしてLambda関数を使用
- Lambdaプロキシ統合を使用
クライアント
-
Postmanを使用
※認証にAWS_IAMを使用する場合、署名バージョン 4 の署名をHTTPリクエストヘッダに乗せる必要がある
※バージョン 4 の署名はPostmanの機能で対応可能、またはSDKを使用して署名を作成可能
AWSマネジメントコンソールでのAPI作成手順
API作成
1.REST APIの構築をクリック
2.API名を入力、エンドポイントはリージョンを選択
リソースの作成
1.アクションからリソースの作成をクリック
2.リソース名を入力、パスパラメータとして設定する場合はリソースパス欄の値を"{}"で囲む
3.以下のようにリソースが追加される
メソッドの追加
1.メソッドの作成をクリック
2.メソッドを選択し☑をクリック
3.統合タイプをLambda関数、Lambdaプロキシ統合を使用をチェック、実行するLambda関数名を入力
4.各リソース、各メソッドについて同様にメソッドを作成
メソッドリクエスト設定
1.メソッドリクエストのリンクをクリック
2.許可欄でAWS_IAMを選択し☑をクリック
### CORS(Cross-Origin Resource Sharing)ブラウザがオリジン(HTMLを読み込んだサーバのこと)以外のサーバからデータを取得する仕組み
Webアプリケーション等からAPI Gatewayにアクセスする場合、HTMLの読み込み先と、API Gatewayではオリジンが異なるためアクセスができない
その場合は、以下のCORSの有効化を行う
Lambdaプロキシ統合を使用している場合は以下のようにLambda側でレスポンスヘッダを設定する必要がある
return {
'statusCode': 200,
'headers': {
'Access-Control-Allow-Headers': 'Content-Type',
'Access-Control-Allow-Origin': '*',
'Access-Control-Allow-Methods': 'OPTIONS,POST,GET'
}
}
参考:
AWS APIGateway + Lambda プロキシ統合 の利用でCORS設定にはまった話
REST API リソースの CORS を有効にする
APIのデプロイ
1.APIのデプロイをクリック
2.任意のステージ名を指定してデプロイ
3.ステージを選択、URLを確認
バックエンドとして動作するLambdaサンプル
- デバイス設定情報
# device settings
deviceSettings = [
{
'deviceId': 1,
'power': 'ON',
'torque': 20,
'angle': 45
},
{
'deviceId': 2,
'power': 'OFF',
'torque': 12,
'angle': 30
},
{
'deviceId': 3,
'power': 'ON',
'torque': 90,
'angle': 70
}
]
1.全デバイスの設定取得
import json
def lambda_handler(event, context):
return {
'statusCode': 200,
'body': json.dumps(deviceSettings)
}
2.指定したIDのデバイス設定取得
import json
def getSettings(id, items):
for item in items:
if item['deviceId'] == id:
return item
return None
def lambda_handler(event, context):
id = int(event['pathParameters']['deviceid'])
item = getSettings(id, deviceSettings)
return {
'statusCode': 200,
'body': json.dumps(item)
}
以下Lambda単体でのテスト用データ
{
"pathParameters": {
"deviceid": 1
}
}
3.指定したIDのデバイス設定更新
import json
def getSettings(id, items):
for item in items:
if item['deviceId'] == id:
print(f'item : {item}')
return item
return None
def lambda_handler(event, context):
id = int(event['pathParameters']['deviceid'])
settings = json.loads(event['body'])
item = getSettings(id, deviceSettings)
for key in settings.keys():
if key in item:
item[key] = settings[key]
return {
'statusCode': 200,
'body': json.dumps(item)
}
以下Lambda単体でのテスト用データ
{
"pathParameters": {"deviceid": 1},
"body": "{\"power\":\"OFF\",\"torque\": 50}"
}
API Gattewayテスト
1.テストをクリック
2.パスパラメータ、リクエスト本文を入力してテストボタンをクリック、右側に結果が表示される
3.動作に不具合がある場合、Lambda単体でのテストや、CloudWatchで動作を確認する
Postmanからのアクセス
1.Authorizationタブから、TYPEにAWS Signatureを選択、API Gatewayにアクセス可能なIAMユーザのアクセスキー、シークレットキーと、リージョン、サービス名を入力
2.メソッドを選択、URIを入力し、Sendをクリックし、正常に動作するとレスポンスが受信される
参考