CodeZine(コードジン)

特集ページ一覧

サーバレスアーキテクチャとは何か?~AWS LambdaとAPI Gatewayによる簡単なAPIの実装を試す

サーバレスアーキテクチャによるアプリケーション開発実践入門 第1回

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2017/08/10 14:00

目次

AWSでサーバレスアーキテクチャを試す

 それでは実際にAWS Consoleから、LambdaとAPI Gatewayによる簡単なAPIの実装を試してみましょう。

 今回実装するAPIは以下の通りです。

  • GETリクエストに対してHello, Lambda!の文字列を返却する
  • クエリストリングにnameが含まれている場合は、Hello, ${name}!の文字列を返却する
  • GET以外のメソッドに対しては、405(Method Not Allowed)のHTTPステータスコードを返却する

Lambda関数の作成

 AWSマネジメントコンソールから、[Lambda]をクリックします。

 Lambdaの画面で、[今すぐ始める]をクリックします

 もし、すでに作成したLambda関数がある場合は、[Lambda 関数の作成]をクリックします。

(1)設計図の選択

 まずは設計図(blueprint)を選択します[3]

 利用する言語やシナリオを元に設計図を選択し、必要に応じてカスタマイズすることができます。

 今回はランタイムに[Node.js 6.10]を選択し、その中の[hello-world]テンプレートを用います。

[3] 設計図とは、Lambda関数のトリガーとなるイベントソースと、そのイベントソースに対応したLambda関数のテンプレートです。設計図を用いないで独自にイベントソースやLambda関数を開発することも可能です。

(2)トリガーの設定

 このテンプレートでは、トリガーとなるイベントソースがデフォルトでは設定されていません。

 [API Gateway]を選択し、API Gatewayのプロキシ統合タイプをイベントソースとして設定します。

  1. [API名]に「lambda-first-api」と入力
  2. [デプロイされるステージ]はデフォルトの「prod」を選択
  3. [セキュリティ]は「オープン」を選択

 入力ができたら、[次へ]をクリックします。

(3)関数の設定

 続いて関数の設定を行います。

 ここで、API Gatewayが受け付けたリクエストに対して、どのようなレスポンスを返却するかを定義します。

 [名前]に「hello-lambda」と入力します。

 Lambda関数のコードの下にある、「Lambda関数ハンドラおよびロール」セクションで以下の通り設定します。

  1. [ロール]で「テンプレートから新しいロールを作成」を選択
  2. [ロール名]に「hello-lambda-role」と入力
  3. [ポリシーテンプレート]で「シンプルなマイクロハーネスのアクセス権限」を選択

 「Lambda関数のコード」セクションでは、Lambdaで実行されるコードを設定します。今回は「コードをインラインで編集」機能を利用して直接JavaScriptを記述していきますが、[コード エントリ タイプ] で選択できるように、.zipファイルでのアップロードやS3経由でのファイルアップロードも行うことが可能です。

 今回利用するLambda関数のコードは以下の通りです。

javascript
'use strict';

console.log('Loading function');

exports.handler = (event, context, callback) => {
    let response;

    switch (event.httpMethod) {
        case 'GET':
            let name = 'Lambda';
            if (event.queryStringParameters && event.queryStringParameters['name']) {
                name = event.queryStringParameters.name;
            }
            response = {
                statusCode: 200,
                body: `Hello, ${name}!`
            };
            break;
        default:
            response = {
                statusCode: 405,
                body: 'Method Not Allowed'
            };
            break;
    }

    callback(null, response);
};

 Lambda 関数で利用可能な引数は以下の通りです。

  • event:API Gatewayから渡されるリクエストのイベントデータ
  • context:実行中のLambda関数のランタイムの情報
  • callback:呼び出し元であるAPI Gatewayにレスポンスを返す際に使用するコールバック関数

 API Gatewayのプロキシ統合タイプではstatusCodeだけでなく、必要に応じてbodyheadersを含むレスポンスオブジェクトを返却する必要があります。

 eventに含まれるリクエストの情報に基づいて必要な処理を行った上で、レスポンスオブジェクトを組み立て、API Gatewayにcallbackを返却するという流れが基本となります。

 全ての設定及びLambda関数のコードの入力が完了したら、[次へ]をクリックします。

(4)確認

 設定内容を確認し、問題がなければ[関数の作成] をクリックします。

(5)実行

 関数が作成されたら、実際に動かしてみましょう。

  1. [トリガー]タブを選択します
  2. エンドポイントに割り振られたURLをクリックします

 ブラウザにHello, Lambda!と表示されます。

 続いて、URLに?name=Johnのクエリパラメータを追加すると、Hello,John!とレスポンスが動的に変更されることが確認できます。

(6)API Gatewayの確認

 以上でAPIの実装は完了ですが、API Gatewayの設定も少し見てみましょう。

 [prod]のリンクをクリックすると、API Gatewayの設定ページに遷移します。

 [lambda-first-api]の[リソース]をクリックし、[/hello-lambda]以下の[ANY]をクリックすると、API全体の流れを確認することができます。

 lambda-first-apiAPIのhello-lambdaリソースでANYを定義した結果「全てのメソッドに対して統合リクエストタイプLAMBDA_PROXYを経由してLambda関数hello-lambdaを呼び出す」という設定が行われています。

 これにより、API Gatewayによって適切なLambda関数が呼ばれ、関数内のソースコードが実行された結果をHTTPレスポンスとしてクライアントへ返却することが可能になっています。

 [統合リクエスト]をクリックすると、API GatewayとLambda関数がどのように連携されているかを確認することができます。

 API Gatewayにはリクエストをどのようにハンドリングするかを決定するいくつかの「統合タイプ」が存在しますが、Lambda関数と連携する際は[Lambda関数]を選択します。

 その中のオプションの一つとして「Lambdaプロキシ統合」というものが存在します。

 これを有効にすると統合タイプが「LAMBDA_PROXY」に、無効にすると「LAMBDA」となります。

 統合タイプが「LAMBDA」の場合、リクエスト情報をLambda関数に渡すためのマッピングを明示的に設定する必要があり、またLambdaから返された結果を正規表現で検証し、適切なHTTPステータスコードを付与する必要があります。

 その一方で、Lambda関数側は、API Gatewayでマッピングされた値がevent引数で渡され、callbackで返却する値がそのままAPI Gatewayのレスポンスボディとなる、シンプルなものとなります。

 対して統合タイプが「LAMBDA_PROXY」の場合は、API GatewayでのマッピングやHTTPステータスコードの設定が不要となりますが、コードの説明でも述べたようにstatusCodebodyheadersなどレスポンスに必要な情報を全てLambda関数の実行結果として返す必要があります。

 「LAMBDA_PROXY」タイプには、以下のような制約が存在します。

  • レスポンスに必要な情報を全てcallbackの第二引数に渡す必要がある
  • レスポンスのbodyはstring型である必要がある
  • Lambdaが返却する値の型が不正であったりエラーで終了した場合、必ずHTTPステータスコードが502のInternal Server Errorのレスポンスが返される
  • headersの設定をLambda関数で行うため、API Gatewayの持つCORSの機能を用いることができない

 「LAMBDA_PROXY」タイプは「LAMBDA」タイプと比較し、マッピングなどの複雑な設定を行うことなく利用することができますが、ステータスコードの適切な付与や、コード実行時のエラーハンドリングなどに考慮したコードを実装する必要があります。

 単純なAPIであれば「LAMBDA」統合タイプを、複数のクエリパラメータを有していたり、リクエストヘッダーの情報を利用するような複雑なAPIの場合は「LAMBDA_PROXY」統合タイプを用いるといったように、APIの挙動に合わせて使い分けることをお勧めします。

まとめ

 以上のように、AWSマネジメントコンソールのみを用いても、動的なAPIを簡単に作成することができます。

 今回はリクエストに応じて動的なレスポンスを返す単純なAPIを作成しましたが、SESとS3 、Lambdaを組み合わせることで、ランディングページなどで使うお問い合わせフォームなども、別途Webサーバやデータベースなどを用意することなく、簡単かつ安価に作成することができます。

 次回以降の連載では、AWSの上でサーバレスアーキテクチャを用いて、SPAを実装していきたいと思います。

参考URL



  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2017/08/10 15:04 表1 FaaSの提供範囲のところで「スクリプトの実行環境」とすべきところが「スクリプトの実行環」となっていたので修正しました。

バックナンバー

連載:サーバレスアーキテクチャによるアプリケーション開発実践入門

著者プロフィール

  • 瀬筒 貴仁(セヅツ タカヒト)

     株式会社インキュビット R&D 統括マネージャー / みらい合同会社 代表社員  バージョン 1.0 から Ruby on Rails エンジニアとして活動する他、HTML/CSS/JavaScriptエンジニア、Webアプリケーション開発のUI/UX担当なども手がけています。現在はWE...

  • 三宅 暁(ミヤケ アキラ)

    株式会社ウェルビー 開発部   フロントエンドを中心に、クラウドを用いた Web サービスのアーキテクチャ設計から継続的な開発の仕組み作りや実装まで行うプログラマ。 「目的を達成するためにより良い方法を」を念頭に、新しい考え方や技術を積極的...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5