Lambdaを使用したアプリケーション作成のLambda関数呼び出しを AWS API Gateway を通して呼び出すようにします。

サンプルコードは、以下からダウンロードできます。

API Gateway の API作成

Lambdaを使用したアプリケーションで作成したLambda関数をAWS API Gateway から呼び出すようにするため、API Gateway のAPI を作成します。
そして、Lambda関数との結び付けと、API Gateway を呼び出すための IAM Role を指定します。

API の作成

  1. AWS API Gateway コンソールで、「Create API」をクリックして、API Gateway の API の作成を開始します。
  2. New API 画面で、API name 等を入力します。
    フィールド名 設定値
    API name MyNoteAPI
    Clone from API 「Do not clone from existing API」を選択
    Description 説明を入力
  3. 「Create API 」をクリックします。
  4. Resources で、Actions → Create Resourcce をクリックし、Resource を作成し、その中に Method を作成します。
  5. New Create Resource 画面で、以下のように Resource name 等を入力して「Create Respource」をクリックします。、
    フィールド名 設定値
    Resource name MyNoteFunc
    Resource Path 自動的にに、/mynotefunc となります。
    「Create resource」をクリックします。
  6. Tree 表示の /mynotefunc を選択し、Actioncs → Create Method をクリックします。
  7. POST を選択します。
  8. POST のパラメータを設定し、「Save」をクリックします。
    フィールド名 設定値
    Integration type Lambda Function
    Lambda Region Lambda 関数のあるリージョンを指定します。
    Lambda Function Lambda 関数名を指定します。
    ここでは、Lambdaを使用したアプリケーションで作成した、Lambda Function名のMyNoteFuncを指定します
  9. 「Add Permission to Lambda Function」というダイアログが表示されるので、「OK」を押して、Method の作成を完了します。

Authorization に IAM を指定

  1. /mynotefunc - POST - Method Execution で、Method Request をクリックします。
  2. Method Request で、Authrization を IAM に変更し、「Updata」チェックマークをクリックします。
    この指定で、IAM 認証で、API Gateway を使用できるようになります。
  3. Method Execution に戻って、Integration Request を選択します。

    Invoke with caller credntials のチェックボックスをチェックして、Method Execution に戻ります。
    この指定をすることで、API Gateway 経由で、Lambda Function を呼び出したときに、Cognito の認証ユーザーIDが、context.identity.cognitoIdentity で受け渡されます。
    Lambda 関数の MyNoteFunc では、context.identity.cognitoIdentity で、ユーザーID を特定しているので、この設定が必要です。

CORS の設定

Cross-Origin Resource Sharing(CORS)設定をすることで、API Gateway のendpoint から、Lambda Function を呼び出せるようにします。
  1. Tree 表示の /mynotefunc を選択して、「Actions」→「Enable CORS」 を選択します。
  2. /mynotefunc Enable CORS 画面が表示されます。
  3. Enable CORS の画面で、method は、POST とOPTION がチェックされていることを確認します。
  4. Access-Control-Allow-Headers を以下のように設定します。
    1. 'Content-Type,X-Amz-Date,Authorization,x-amz-security-token'
    2. 初期状態では、X-Api-Key が指定してありますが、今回は、API-Key ではなく、ユーザー認証を使用するので、x-amz-security-token が必要となります。
      x-amz-security-token に関しては、AWS のドキュメントの「一時的なセキュリティ認証情報を使用して AWS リソースへのアクセスをリクエストする」に情報があります。
  5. 「Enable CORS and replace existing CORS headers」をクリックします。
  6. 確認画面が表示されるので、「Yes, replace existing values」をクリックして、CORSの設定を完了します。

API の deploy と、SDk のダウンロード

API Gateway を depoly すると、クライアント側の呼び出しに使用するSDK をダウンロードすることができます。
  1. Resource View の 「Deploy API」をクリックし、API Gateway の deploy を開始します。

  2. Deploy API 画面の、Development stage で、[New Stage] を選択します。
  3. Stage name に「TEST」等を指定して、「Deploy」をクリックし、Deployします。
  4. Deploy が終了したら、SDK Generation タブをクリックします。

    Platform をJavaScript とします。
    「Generate SDK」をクリックすると、SDK の ZIP ファイルがダウンロードされます。
    クライアント側のコード作成に使用するので、保存しておきます。

クライアント側のIAM Role 設定

認証したユーザーが API Gateway にアクセスできるようにするため、IAM Roleにアクセス権を追加します。

ポリシーの作成

  1. AWS IAM コンソールで、「ポリシーの作成」をクリック
  2. Policy Generator を選択し、以下の値設定します。
    フィールド 設定値
    AWS サービス Amazon API Gateway
    アクション Invoke をチェックします。
    Amazon リソースネーム API Gateway の /mynotefunc の POST method の ARN を指定します。
    「ステートメントを追加」して「次のステップ」をクリックします。
    「ポリシーの確認」画面で、ポリシー名を mynote_func_api_gateway_invoke と入力して、「ポリシーの作成」をクリックします。

ロールの作成

  1. AWS IAM コンソールで「新しいロールの作成」をクリックします。
  2. ロール名をmynote-cognito-api-gatewayとします。
  3. Cognitoを使用したアプリケーションの時と同じように、ロールタイプの選択で、「IDプロバイダアクセス用のロール」の「ウェブIDプロバイダにアクセスを付与」を選択し、Role 作成します。
  4. ポリシーのアタッチで、先ほど作成した、mynote_func_api_gateway_invoke と、Lambdaを使用したアプリケーションで作成した、mynote_func_lambda_invoke の二つをアタッチします。
  5. cognito.js の m_roleArn に作成したRole のARNを指定します。

API Gateway の呼び出しの実装

  1. ダウンロードしたSDK を展開し、クライアントのプログラムに組み込みます。
    1. ダウンロードしたSDKを展開した中にある、lib ディレクトリと、apigClient.js を使用します。
    2. apigClient.js に API Gateway の呼び出し関数定義があります。
      以下のようにして使用します。
      var apigClientFactory.newClient();
      apigClient.mynotefuncPost(params, body, additionalParams)
      				
    3. libディレクトリ、apigClient.js は以下に置きます。
      public
        |
        +- lib ここに、lib ディレクトリをそのままコピー
        |
        +- js ここに、apigClient.js を配置
      				
  2. dbControllerApiGateway.js で、API Gateway の呼び出しを行っています。
    var apigClient = apigClientFactory.newClient({
    	accessKey: AWS.config.credentials.accessKeyId,
    	secretKey: AWS.config.credentials.secretAccessKey,
    	sessionToken: AWS.config.credentials.sessionToken,
    	region: AWS.config.region
    });
    console.log('call notefuncPost');
    apigClient.mynotefuncPost(params, body, additionalParams)
    		
  3. Invoke 関数で、API Gateway の API を呼び出しています。
    以下のコードとなっています。
    function invoke(body, callback) {
    	var params = {};
    	var additionalParams = {};
    
    	var apigClient = apigClientFactory.newClient({
    		accessKey: AWS.config.credentials.accessKeyId,
    		secretKey: AWS.config.credentials.secretAccessKey,
    		sessionToken: AWS.config.credentials.sessionToken,
    		region: AWS.config.region
    	});
    	console.log('call notefuncPost');
    	apigClient.mynotefuncPost(params, body, additionalParams)
        .then(function(result){
    		var str = JSON.stringify(result, null, 2);
        	if (result.data.errorMessage) {
        		cnsole.log('lambda error occurred : ' + str);
    			callback(false, result.data);
        	} else {
    			console.log('success :' + str);
    			callback(true, result.data);
    		}
    	}).catch( function(result){
    		console.log('error:' + JSON.stringify(result, null, 2));
    		callback(false, result);
    	});
    }
    
    this.getNoteList = function(userId, callback) {
    	var payload = {
    		func : 'getNoteList',
    		param : {}
    	};
    	invoke(payload, function(isSuccess, data) {
    		if (isSuccess) {
    			callback(true, data.operation, data.notes);
    		} else {
    			callback(false, data, null);
    		}
    	});
    };
    		
  4. index.html への組み込み
    1. Lambda 版と同様に、dbController を切り替えるだけで、使用できるようになります。
      function initApp() {
      
      	…
      	
      	g_dbControllerApiGateway = new DbControllerApiGateway();
      	g_dbControllerApiGateway.init();
      	g_doc.setDbController(g_dbControllerApiGateway);
      				

動作確認

Node.js のローカルサーバーで動作を確認します。
確認後、AWS S3 にアップロードし、動作確認します。

サンプルコードの実行方法

  • mynote-sample-api-gateway.zip をダウンロードしてください。
  • ダウンロード後、zip ファイルを展開してください。
  • zipファイルの中には、Node.js のmodule は含まれていないので、npm install で、各 module のインストールが必要です。
    c:\projects>cd mynote
    c:\projects\mynote>npm install
    		
  • mynote\public\index.html のリージョン名を指定してください。
    var g_region = '<リージョン名>';
    		
  • mynote\public\js\cognito.js のIAM Role の ARN, Cognito Identity pool ID を指定してください。
    var m_roleArn = '<Role ARN>';
    var m_identityPoolId = '<cognito identity pool id>';
    		
  • mynote\NoteCreateTable.js のリージョン名を指定してください。
    var region = "<リージョン名>";
    		
  • lambda function は、zip を展開した root directory の mynote_lambda.js にあります。
  • API Gateway のコンソールの「Generation SDK」で作成した SDK を以下にコピーしてください
    • apigClient.js を public\js ディレクトリにコピーしてください
    • lib ディレクトリを public ディレクトリにコピーしてください