読者です 読者をやめる 読者になる 読者になる

順次、選択、そして繰り返し

プログラミングのことやITのこと、たまに演劇のことも書きます。

APIGatewayからAWSLambdaを叩く(POST送信)

『サーバーレスアーキテクチャ』という言葉にひかれて、
APIGatewayからAWSLambdaを叩いてみた。
そして、色々詰まったのでメモとして残しておく。


まずはAPIGatewayの設定。

メソッドリクエストの設定。
f:id:sndstudy:20170118005347p:plain

リクエスト本文のコンテンツタイプに
application/x-www-form-urlencoded を設定する。
これを設定することFormの値をPOSTメソッドでも送信することができる。

統合リクエストの設定。
f:id:sndstudy:20170118005833p:plain
f:id:sndstudy:20170118005856p:plain

本文マッピングテンプレートのコンテンツタイプは
メソッドリクエストと合わせる。
また、ここでリクエストボディに詰められた
Formの値を取り出すためにマッピングテンプレートを設定する。

マッピングテンプレートはVTLで記述する。
Velocityの文法 - Javaについて

{
    "headers" : {
        #foreach( $key in $input.params().header.keySet() )
            "$key" : "$input.params().header.get($key)"#if( $foreach.hasNext ),#end
        #end
    },
    "queryParameters" : {
        #set( $tmpstr = $input.body )
        #foreach( $keyandvaluestr in $tmpstr.split( '&' ) )
        #set( $keyandvaluearray = $keyandvaluestr.split( '=' ) )
            "$keyandvaluearray[0]" : "$keyandvaluearray[1]"#if( $foreach.hasNext ),#end
        #end
    },
    "stage" : "$context.stage",
    "sourceIp" : "$context.identity.sourceIp",
    "userAgent" : "$context.identity.userAgent"
}

特にこの部分でFormで送信したkeyとvalueを取り出している。

    "queryParameters" : {
        #set( $tmpstr = $input.body )
        #foreach( $keyandvaluestr in $tmpstr.split( '&' ) )
        #set( $keyandvaluearray = $keyandvaluestr.split( '=' ) )
            "$keyandvaluearray[0]" : "$keyandvaluearray[1]"#if( $foreach.hasNext ),#end
        #end

統合レスポンスの設定。
今回はFormで2つの値を送信し、足し算を行った結果を
htmlで表示するためコンテンツタイプを
text/htmlに設定する。

f:id:sndstudy:20170118010532p:plain

本文テンプレートは以下のように、計算結果を表示するように記述。

<html>
    <head>
        <title>title</title>    
    </head>
    <body>
        <span>$input.path('ans')</span>
    </body>
    
</html>


メソッドレスポンスでは、
統合レスポンスと同様にtext/htmlを設定する。
f:id:sndstudy:20170118010941p:plain

次はLambdaの作成。
今回はNode.jsで作成。

f:id:sndstudy:20170118011146p:plain

exports.handler = (event, context, callback) => {
    
    //値を取得する
    var num1 = parseInt(event.queryParameters.param1);
    var num2 = parseInt(event.queryParameters.param2);
    var answer = num1 + num2;
    
    //レスポンス
    context.done(null, {"ans": answer});
    
};

最後はFormを送信するhtmlを作成。

index.html

<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="UTF-8">
    <title>LambdaTest</title>

</head>
<body>
    
    <form action="create api url" method="post">
        
        値1:<input type="text" name="param1"><br>
        値2:<input type="text" name="param2">
        
        <input type="submit" name="test">
    </form>

</body>
</html>

実行結果はこんな感じ。
f:id:sndstudy:20170118011543p:plain
f:id:sndstudy:20170118011701p:plain

特に詰まったのは統合リクエストのマッピングテンプレートだった。
VLTは初めてだったので、処理を書くのに時間がかかった。

あと、今回APIを作成したおかげでGETとPOSTのリクエストの中身を
細かく知ることができてよかった。(POSTはリクエストボディがあるなど)


■参考サイト
API Gateway + Lambda にFormからPOSTする時のマッピングテンプレートを作成しました | Developers.IO
[Web] HTTPリクエストの中身を学んでみた。GETやPOSTの違いなど - YoheiM .NET
HTTP入門
Amazon API Gatewayをブラウザから呼んでみた | Developers.IO
パーセントエンコーディング - Wikipedia
application/x-www-form-urlencoded ‐ 通信用語の基礎知識
node.jsのcontext.succeedで気をつけること | hacknote
docs.aws.amazon.com