58
63

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 5 years have passed since last update.

AWS LambdaをREST API Serverっぽく使ってみる

Last updated at Posted at 2015-06-22

はじめに

AWS SummitのLambda関連のSessionに触発されてLambdaを色々触っていますが、Lambdaを既存のREST APIのServerの置き換えとして使えないか、という検討をしたメモをチラシの裏しておきます。

AWS Summitの資料はこちらにあります。Lambda関連のSession資料は以下2つ。

追記

AmazonがAPI GatewayというServiceを発表しました。これを使えば、従来のREST API→API Gateway→Lambdaとつなげる事で、EC2無しでServer環境を作る事が可能になります。つまり、この記事に有る様なREST APIを無理矢理Amazon SDKへ変換して処理する必要は無くなります。

Server/Clientの構成概要

Server側

現在、Server側のCodeであるLambdad functionは、Node.jsとjavaで書く事が可能です (javaが先日サポートされました)。ここではNode.jsを使い、Clientから送られて来た文字列を、全部大文字にして返す、と言う実装をCase studyとしています。

Client側

Buttonをclickすると、Text inputの中身を取り出してJSONにして、AWS SDK for JavaScript in the BrowserLambda関連のMethodをCallする、というhtmlを実装してみます。Responseの文字列とResponseに要した時間を表示してくれます。

AWS SDKを使うと処理が隠蔽されますが、CallしたMethodは、最終的にはhttps://lambda.us-east-1.amazonaws.com/2015-03-31/functions/へのPOST処理を行ってくれます。

事前準備

こちらを参考に、以下をしておいてください。

  • Lambda functionの作成
  • Lambda functionを(AWSの内部で)動かす為のIAM roleの作成と権限の設定
  • Lambda functionを(AWSの外部から)呼び出す為のIAM Userの作成と権限の設定、
    作成したIAM UserのAccess Key IdSecret Access Keyの取得

上記Pageでは一部説明が省略されていますが、以下の2つのIAM関連の設定が必要です

  • IAM role:
    起動されたLambda functionの為のAccess権の設定、今回はLambda functionからS3やDynamoへアクセスは無いので、Roleは空でOK
  • IAM user:
    Lambda functionを外部から呼び出す為のUserで、このUserへのLambda functionの実行権限の付与と、このUserに対するAPI Key, Secret keyの作成が必要

Server側のLambda functionのcode

たった4行ですが、Client側jsからPOSTされたJSONは、context["clientContext"]に入って居ます。このKeyValueの["key1"]という要素を取り出して、toUpperCaseで大文字にして、Responseとして返します。

exports.handler = function(event, context) {
    context.succeed(context["clientContext"]["key1"].toUpperCase());
    context.fail('Something went wrong');
};

Client側のjavascriptのcode

以下をxx.htmlとして保存して実行してみてください。

個別に設定が必要なのが accessKeyIdsecretAccessKey,region, FunctionNameの4つです。

  • accessKeyIdsecretAccessKeyは上記で作成した物を使ってください。以下のCodeの文字列は適当です
  • regionはここではUS Virginia = us-east-1としていますが、使っているAWS Regionの名前を入れてください
  • FunctionNameは作成したLambda functionの名前と同じ物にする必要が有ります

<!DOCTYPE html>
<html>
<head lang="en">
    <script src="https://code.jquery.com/jquery-2.1.4.js"></script>
    <script src="https://sdk.amazonaws.com/js/aws-sdk-2.1.34.min.js"></script>
    <script src="https://rawgit.com/dankogai/js-base64/master/base64.min.js"></script>
    <meta charset="UTF-8">
    <script type="text/javascript">
        $(document).ready(function(){
            $("#submit1").click(function(){
                executeLambda();
            });
        });
        executeLambda = function() {
            $("#submit1").attr("disabled", true);
            var startTime = new Date();
            AWS.config.update({accessKeyId: "AKIAJD66ABCDEFGHIJ", secretAccessKey:
                    "2CRDGTJZT9E42KC8GhxrcXXXrKyx7974634634fbsdfs" ,region:"us-east-1"});

            inputText = $("#input1").val();
            var input = {key1:inputText};
            var context = Base64.encode(JSON.stringify(input));
            var lambda = new AWS.Lambda();
            var params = {
                FunctionName:"API_Test",
                InvocationType:"RequestResponse",
                ClientContext:context
            };
            lambda.invoke( params,function(err,data) {
                var endTime = new Date();
                if(err) {
                    $("#lambdaResponse").append("<b>Error</b><br>");
                    console.log(err,err.stack);
                }
                else {
                    var responseTime = endTime - startTime;
                    $("#lambdaResponse").append("<b>Response = </b>" + data['Payload'] 
                                              + ", <b>Response time = </b>" + responseTime +  "msec<br>");
                }
                $("#submit1").attr("disabled", false);
            });
        };
    </script>
    <title>AWS Lambda invoke test</title>
</head>
<body>
    <input type="text" id="input1" style="width: 200px;">
    <button type="button" id="submit1">Send to Lambda</button>
    <div id="lambdaResponse"></div>
</body>
</html>

実際に使ってみて

Performance

  • htmlでbuttonをclickしてresponseを得るまでで、早いと250 msec、遅いと8000 msecぐらい掛かります。比較用に同じくAWS US Virginiaに、ほぼ同様の処理をするnode.js serverを立ち上げてアクセスして見たところ、概ね100-400 msecでした
  • Lambda function自体にCacheの機能があるとの事で、前回起動されてから間を空けずに再度起動された場合には処理が早くなると思います
  • LambdaがTokyo regionにもサポートされたら、また測定してみたいと思います

今後の改善に期待した所

  • Lambda function側の処理結果と標準出力のLogはCloudWatchのlogに吐き出されますが、Log UIが激しく使いにくいです
58
63
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
58
63

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?