19
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

AWS API Gateway基本知識まとめ、Lambda連携手順

Last updated at Posted at 2020-10-17

記事について

Amazon API Gatewayの基本情報まとめ

Amazon API Gatewayの位置づけについて

さまざまな機能、処理をWeb APIとして提供
実際に処理を行うバックエンドとしてはLambda関数、各種AWSサービス、インターネット経由で呼び出し可能なURL+メソッド等

1.png

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のデバイス設定更新

メソッド設定

リソースに設定した各メソッドに対して、
一連のフロー(クライアントからのリクエスト → バックエンドでの処理 → クライアントへのレスポンス)を設定する
以下のようにメソッドリクエスト、統合リクエスト、統合レスポンス、メソッドレスポンスの設定を行う

x

メソッドリクエスト

クライアントからのリクエスト受付に関する設定
以下のような設定を行う

  • メソッドをコールするための認証(権限を持ったIAMユーザのみコール可能等)
  • 受け付けるクエリパラメータ
  • 必須とするHTTPヘッダ

※パスパラメータ:一意のリソース特定に使用するパラメータ、ID等
※クエリパラメータ:省略可能なパラメータ

統合リクエスト

バックエンドへのリクエストに関する設定
以下のような設定を行う

  • リクエストの変換
  • バックエンドの種類(Lambda, AWSサービス, HTTP, Mock, VPCリンク)

統合レスポンス

バックエンドからのレスポンスに関する設定
レスポンス内容の変換等

メソッドレスポンス

リクエストに対する最終的なAPI Gatewayとしてのレスポンスに関する設定
レスポンス内のステータスコードや、レスポンスヘッダ等の設定

プロキシ統合の使用(リクエスト、レスポンスの変換を必要としない場合)

リクエスト、レスポンスの変換を必要としない場合、プロキシ統合を使用すると、設定項目を大幅に減らすことが可能
バックエンドがLambda関数の場合、以下のようにLambdaプロキシ統合の使用にチェックを入れる

image-20201016162532696

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の構築をクリック

xx

2.API名を入力、エンドポイントはリージョンを選択

image-20201016142124559

リソースの作成

1.アクションからリソースの作成をクリック

image-20201016171538032

2.リソース名を入力、パスパラメータとして設定する場合はリソースパス欄の値を"{}"で囲む

image-20201016160205404

3.以下のようにリソースが追加される

image-20201016160205405

メソッドの追加

1.メソッドの作成をクリック

2.メソッドを選択し☑をクリック

image-20201016172055518

3.統合タイプをLambda関数、Lambdaプロキシ統合を使用をチェック、実行するLambda関数名を入力

image-20201016170221982

4.各リソース、各メソッドについて同様にメソッドを作成

メソッドリクエスト設定

1.メソッドリクエストのリンクをクリック

xxx

2.許可欄でAWS_IAMを選択し☑をクリック

image-20201016172542451 ### CORS(Cross-Origin Resource Sharing)

ブラウザがオリジン(HTMLを読み込んだサーバのこと)以外のサーバからデータを取得する仕組み
Webアプリケーション等からAPI Gatewayにアクセスする場合、HTMLの読み込み先と、API Gatewayではオリジンが異なるためアクセスができない
その場合は、以下のCORSの有効化を行う

image-20201017094451653

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のデプロイをクリック

image-20201017094451653

2.任意のステージ名を指定してデプロイ

image-20201017094554197

3.ステージを選択、URLを確認

image-20201017094554197

バックエンドとして動作する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.テストをクリック

axx

2.パスパラメータ、リクエスト本文を入力してテストボタンをクリック、右側に結果が表示される

image-20201017111957579

3.動作に不具合がある場合、Lambda単体でのテストや、CloudWatchで動作を確認する

Postmanからのアクセス

1.Authorizationタブから、TYPEにAWS Signatureを選択、API Gatewayにアクセス可能なIAMユーザのアクセスキー、シークレットキーと、リージョン、サービス名を入力
2.メソッドを選択、URIを入力し、Sendをクリックし、正常に動作するとレスポンスが受信される

aaa

参考

19
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
19
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?