LoginSignup
181
172

More than 1 year has passed since last update.

Amazon API Gateway

Last updated at Posted at 2019-08-03

Amazon API Gatewayとは

  • APIの作成:AWS Lambda、EC2、もしくはAWS外でパブリックとして公開されているアプリケーションをAPIとして公開することができます。
  • APIの管理:Amazon API Gatewayは、APIの管理に必要な管理、運用などをお客様側での実施が必要なく、AWS側で提供してくれるマネジどサービスです。

API GAtewayが扱うAPI

プロトコル

REST WebSocket
ステートレス ステートフル
単一HTTPメッセージで1つの操作に関する情報を(理想では)含む
扱う情報をURIで表現する「リソース」として定義し、それらをHTTPメソッド(PUT, GET, POST, DELETE, …)の表現で操作
HTTPの上で、クライアントとサーバー間の双方向通信を実現するための通信仕様
一つのコネクションで継続的なデータ送受信が可能
URIスキームは セキュアWebSocket用の「wss://~」を利用

REST

エンドポイント

エッジ最適化 リージョン プライベート
一旦エッジロケーション(CloudFrontディストリビューション)にルーティング リージョンに直接ルーティング VPC内からAWS PrivateLink = VPCエンドポイント経由でのみアクセス可能

APIの作成

APIは、1個以上のリソースを持ち、各リソースが1個以上のメソッドを持ちます。

API1---リソース1---メソッドGET
API2---リソース2---メソッドGET

各メソッドでは、アップストリームを選択し、
APIクライアント↔API Gateway間のやりとりと、
API Gateway↔アップストリームの間のやりとりを適切に行えるよう、
リクエストおよびレスポンスの変換設定を行います。

設定には、メソッドリクエスト、メソッドレスポンス、統合リクエスト、統合レスポンスの4つがあります。

設定 説明
1.メソッドリクエスト リクエストに認証が必要か、どのようなクエリパラメータを受け付けるかといったAPI Gatewayの受付設定を行う
2.統合リクエスト アップストリームの指定、リクエストボディの変換といったAPI Gatewayとアップストリーム間の統合設定を行う
3.統合レスポンス ステータスレコードのマッピング、レスポンス内容の変換といったアップストリームとAPIGateway間の統合設定を行う
【2.統合リクエスト】で「統合プロキシを統合」を指定した場合は設定不可
4.メソッドレスポンス ステータスレコードごとのレスポンスヘッダーやレスポンスボディの設定といったAPI Gatewayからクライアントへのレスポンス設定を行う

APIの公開

作成したAPIを外部に公開するためにはデプロイを行います。
各APIはデプロイ先としていくつかのステージを持ち、それぞれ異なるバージョンのAPIを公開することができます。
例えば、testステージを用意し動作に問題ないことが確認できたら、prodステージを用意するといったことが可能です。
カスタムドメイン名を設定することも可能です。
(例)
https://api.example.com/prod
https://api.example.com/staging
https://api.example.com/dev

WebSocket

URL

接続(wss)とWebSocket用(https)に2つのURLが提供される。

ルート

  • 3つののルートが定義される。
    • $connect (接続時)
    • $disconnect (切断時)
    • $default (デフォルト)

設定

設定 説明
1.ルートリクエスト *RESTと同じ
2.統合リクエスト *RESTと同じ
3.統合レスポンス *RESTと同じ

アクセス制御

  • リソースポリシー(REST APIのみ)
    JSON形式のリソースポリシーを定義することで、API Gatewayの
    どのリソースに、
    どのアクセスからの、
    どのようなアクションを許可、または拒否
    するかを指定できます。

  • IAM認証
    APIの各要素へのアクセス権限を設定したIAMポリシーを作成し、IAMユーザやIAMロールに付与することで、APIへのアクセスの制御が可能になります。
    これには、対象の各APIメソッドでIAM認証を有効化する必要があります。

  • Lambdaオーソライザー
    Lambda関数を作成することで、認証プロバイダーでの認証結果を元に、APIへのアクセス制御をメソッド単位で行えるようになります。
    1.認証プロバイダーで認証を行い、トークンを取得する。
    2.トークンを含めてAPIリクエストを行う。
    3.API Gatewayがそのトークンの値を元にLambdaオーソライザーで認可を行う。
    4.認可の結果を元にAPIGatewayがリクエスト許可または拒否をする。

  • Cognitoオーソライザー
    認証プロバイダとしてCognitoユーザープールを用いて、APIへのアクセス制御をメソッド単位で行うことも可能です。仕組みはLambdaオーソライザーと似ていますが、この場合はLambda関数を作成する必要はありません。
    1.Cognitoユーザープールで認証を行い、トークンを発行する。
    2.トークンを含めてAPIリクエストを行う。
    3.APIGatewayがそのトークンの値を元にCognitoユーザープールで認可を行う。
    4.認可の結果を元にAPIGatewayがリクエスト許可または拒否をする。

統合リクエスト

統合リクエストタイプ 説明
Lambda Lambda関数を指定して呼び出す。クロスリージョン、クロスアカウントでの呼び出しに対応。
HTTP インターネット経由で呼び出し可能なURL(HTTPS)とメソッドを指定して呼び出す。パブリックに到達可能なエンドポイントであれば実装場所は問わない
Mock モックとしてAPI Gatewayで直接、固定的な応答を返す。統合レスポンスのマッピングテンプレートで実際のモック応答データを設定
AWSサービス AWSサービスを直接呼び出して、各サービスで用意されているアクションを実行
VPCリンク NLBを参照する「VPCリンク」を登録しそれを経由してVPC内リソースへアクセス。エンドポイントURLとしてNLBホスト名を指定

詳しくは、AWS Black Beltを確認することをおすすめする。

なお、プロキシ統合についても確認しておく。
image.png

APIの管理

スロットリングと使用量プラン

アップストリームで処理するリクエスト数が大きくなりすぎないように、リクエスト数を制限することができる。
AWSアカウント単位、メソッド単位、APIキー単位で制御することができます。
レート(1秒あたりのリクエスト数)とバースト(リクエストの同時実行数)で設定します。

APIキーとは
API Gatewayの使用量を制限するために発行するアクセスキーです。
APIキーの使用量制限はそれぞれのAPIキーに対して設定するのではなく、使用量プランという設定項目でスロットリング設定を行い、APIキーを使用量プランに紐付けることで設定します。
レートやバーストの他に、クォータ(日、週、月あたりのリクエスト数)も設定します。

API WAFでの攻撃からの保護

ステージごとに設定することで、SQLインジェクションやクロスサイトスクリプティングといったWebアプリケーションに対する攻撃から保護することができます。

カスタムドメイン

「カスタムドメイン」を登録し、証明書とDNSを設定することで独自ドメイン名で登録したAPIを呼び出し可能 (※エンドポイントタイプが「プライベート」以外)

(例)
エンドポイントURL https://.execute-api..amazonaws.com/)
⬇️
カスタムドメイン https://api.example.com/my-api-id-service

キャッシュ

REST APIでは APIのステージ毎にキャッシュを定義し、バックエンドへのトラフィック削減と低レイテンシの実現に利用可能

カナリアリリース

REST APIの各ステージ(メイン)に紐付く特別なステージ「Canary」を作成し、リクエストを指定の比率でCanaryへ流すことが可能

X-Ray連携

REST APIでは APIステージのログ設定としてAWS X-Rayへの連携によるリクエストのトレースと分析およびデバッグが可能

CloudWatchメトリクス

設定は、「ステージ」から行うことができる。
image.png

詳細メトリクス 説明
4XXError 指定された期間に取得されたクライアント側エラーの数。
5XXError 指定された期間に取得されたサーバー側エラーの数。
CacheHitCount 指定された期間内に API キャッシュから配信されたリクエストの数。
CacheMissCoun API キャッシュが有効になっている特定の期間における、バックエンドから提供されたリクエストの数。
Count 指定された期間内の API リクエストの合計数。
IntegrationLatency API Gateway がバックエンドにリクエストを中継してから、バックエンドからレスポンスを受け取るまでの時間。
Latency API Gateway がクライアントからリクエストを受け取ってから、クライアントにレスポンスを返すまでの時間。

API Gateway API をトラブルシューティングするために CloudWatch ログを有効化するにはどうすればよいですか?

APIドキュメント

利用者が活用しやすく、ドキュメントを公開すべきです。
API Gatewayには、APIに関するドキュメントを作成する機能が用意されています。
この機能を利用すれば、作成したAPIのリソース、メソッド、リクエスト、レスポンスなどの各要素に説明をつけるだけでなく、Swagger(OpenAPI)と呼ばれるAPIドキュメントの標準的な形式に測ったAPIドキュメント定義ファイルを、エクスポートすることができます。エクスポートされたAPIドキュメント定義ファイルは、標準的な形式なので、SwaggerUIなどのツールを利用することで、開発者にとって見やすくデザインされたフォーマットを閲覧できます。
また、これとは逆に、Swagger形式のAPIドキュメント定義ファイルをAPI Gatewayにインポートし、APIの作成を開始することもできます。

利用料金の考え方

スクリーンショット 2019-11-02 21.20.56.png

エラー処理一覧

Handling Errors in Amazon API Gateway

ゲートウェイレスポンスのタイプ

INTEGRATION_FAILURE(504)

統合がタイムアウトした場合のゲートウェイレスポンス。レスポンスタイプが未指定の場合、このレスポンスはデフォルトで DEFAULT_5XX タイプになります。
統合タイムアウトの範囲は、Lambda、Lambdaプロキシ、HTTP、HTTPプロキシ、AWS統合を含むすべての統合タイプの50ミリ秒から29秒です。

Demo(Lambda プロキシ統合による Hello World API の構築)

なお、プロキシ統合の説明については↓の記事がわかりやすいです。
AWS Lambda Proxy Integrationを試してみた

API のバックエンドとなる「Hello, World!」Lambda 関数を作成する

次の関数は、JSON形式で発信者に挨拶を返します。

{
    "greeting": "Good {time}, {name} of {city}.[ Happy {day}!]"
}

関数は、Node.js 8.10で以下のとおり作成する。

Node.js
'use strict';
console.log('Loading hello world function');

exports.handler = async (event) => {
    let name = "you";
    let city = 'World';
    let time = 'day';
    let day = '';
    let responseCode = 200;
    console.log("request: " + JSON.stringify(event));

    if (event.queryStringParameters && event.queryStringParameters.name) {
        console.log("Received name: " + event.queryStringParameters.name);
        name = event.queryStringParameters.name;
    }

    if (event.queryStringParameters && event.queryStringParameters.city) {
        console.log("Received city: " + event.queryStringParameters.city);
        city = event.queryStringParameters.city;
    }

    if (event.headers && event.headers['day']) {
        console.log("Received day: " + event.headers.day);
        day = event.headers.day;
    }

    if (event.body) {
        let body = JSON.parse(event.body)
        if (body.time) 
            time = body.time;
    }

    let greeting = `Good ${time}, ${name} of ${city}.`;
    if (day) greeting += ` Happy ${day}!`;

    let responseBody = {
        message: greeting,
        input: event
    };

    // The output from a Lambda proxy integration must be 
    // in the following JSON object. The 'headers' property 
    // is for custom response headers in addition to standard 
    // ones. The 'body' property  must be a JSON string. For 
    // base64-encoded payload, you must also set the 'isBase64Encoded'
    // property to 'true'.
    let response = {
        statusCode: responseCode,
        headers: {
            "x-custom-header" : "my custom header value"
        },
        body: JSON.stringify(responseBody)
    };
    console.log("response: " + JSON.stringify(response))
    return response;
};

「Hello, World!」 API を Lambda プロキシ統合を使用して作成する

「APIの作成」で書いたように、API → リソース → メソッドの順に作成していきます。

API

「RESET」を選択し、「新しいAPI」を作成する。
image.png

リソース

ここでは、「リソース名」だけを入力する。
image.png

メソッド

ANYメソッドを選択し、先程作成したLambda関数を選択する。
スクリーンショット 2019-08-03 17.07.35.png

次に「APIの公開」で書いたようにデプロイして行きます。

デプロイ

「アクション」-「APIのデプロイ」で適当な名前をつけてデプロイするとURLを作成される。
スクリーンショット 2019-08-03 17.17.24.png

テストする

これでデプロイされたので、アクセスして確認して見ましょう。

https://**********.execute-api.ap-northeast-1.amazonaws.com/test/helloworld?name=naata&city=Japan

リンク

API Gateway - API キャッシュを有効にして応答性を強化する
ステージごとにAPIを作成することなく 各ステージごとにバックエンドポイントを振りわける
API Gatewayのカスタムドメイン,HTTPS,相互TLS認証

181
172
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
181
172