web-dev-qa-db-ja.com

Amazon API GatewayからAWS Lambdaにクエリ文字列またはルートパラメータを渡す方法

例えば私たちが使いたいのなら

GET /user?name=bob

または

GET /user/bob

これら両方の例をLambda関数のパラメータとしてどのように渡しますか?

ドキュメントで「マップ元」を設定することについて何か見ましたが、その設定がAPI Gatewayコンソールで見つかりません。

  • Method Requestページで定義されているmethod.request.path.parameter-nameという名前のパスパラメータのparameter-name
  • Method Requestページで定義されているmethod.request.querystring.parameter-nameという名前のクエリ文字列パラメータの場合はparameter-name

クエリ文字列を定義しても、どちらのオプションも表示されません。

279
MonkeyBonkey

2017年9月現在、リクエストボディにアクセスするためのマッピングを設定する必要はもうありません。

あなたがする必要があるのは、リソースの下のIntegration Requestの下で、 "Use Lambda Proxy integration"をチェックすることだけです。

enter image description here

そうすると、クエリパラメータ、パスパラメータ、ヘッダにアクセスできるようになります。

event['pathParameters']['param1']
event["queryStringParameters"]['queryparam1']
event['requestContext']['identity']['userAgent']
event['requestContext']['identity']['sourceIP']
202
Jonathan

これを機能させるための手順は次のとおりです。

API Gatewayコンソール内で...

  1. Resources -> Integration Requestに行く
  2. テンプレートドロップダウンの横にあるプラスまたは編集アイコンをクリックします(テンプレートフィールドがすでに開いていて、ここのボタンがグレー表示されているのでわかりません)。
  3. デフォルトが表示されていても、content-typeフィールドに明示的にapplication/jsonと入力します(これを行わないと、保存されず、エラーメッセージも表示されません)。
  4. これを入力マッピングに入れます{ "name": "$input.params('name')" }

  5. テンプレートのドロップダウンリストの横にあるチェックボックスをクリックします(これで最終的に保存されると思います)。

198
MonkeyBonkey

このマッピングテンプレートを使用して、本文、ヘッダー、メソッド、パス、およびURLクエリ文字列パラメータをLambdaイベントに提供しました。私はより詳細にテンプレートを説明するブログ記事を書きました: http://kennbrodhagen.net/2015/12/06/how-to-create-a-request-object-for-your-lambda-event-from- api-gateway/

これが使用できるマッピングテンプレートです。

{
  "method": "$context.httpMethod",
  "body" : $input.json('$'),
  "headers": {
    #foreach($param in $input.params().header.keySet())
    "$param": "$util.escapeJavaScript($input.params().header.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "queryParams": {
    #foreach($param in $input.params().querystring.keySet())
    "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end

    #end
  },
  "pathParams": {
    #foreach($param in $input.params().path.keySet())
    "$param": "$util.escapeJavaScript($input.params().path.get($param))" #if($foreach.hasNext),#end

    #end
  }  
}
121
kennbrodhagen

最近では、ドロップダウンテンプレートがAWSのAPI Gatewayコンソールに含まれています。

あなたのAPIのために、リソース名をクリックしてください...そしてGET

「ボディマッピングテンプレート」を展開する

入力してください

アプリケーション/ JSON

content-Typeの場合は(明示的に入力する必要があります)、チェックマークをクリックします。

「テンプレートの生成」という単語とドロップダウンが表示された新しいウィンドウが開きます(画像を参照)。

選択する

メソッド要求パススルー

enter image description here

保存をクリック

変数にアクセスするには、次の構文を使用してください(これはPythonです)。 URL

https://yourURL.execute-api.us-west-2.amazonaws.com/prod/confirmReg?token=12345&uid=5

次のようにして変数を取得できます。

from __future__ import print_function

import boto3
import json

print('Loading function')


def lambda_handler(event, context):
    print(event['params']['querystring']['token'])
    print(event['params']['querystring']['uid'])

ですから、あなたが望む各変数を明示的に命名したりマッピングしたりする必要はありません。

35

受け入れられた答えは私のためにうまく働きました、しかしgimeneteの答えを拡張して、私はすべてのquery/path/headerパラメータを通過するために使用できる一般的なテンプレートを望みました、そして私は次のテンプレートを思いつきました。誰かが便利だと思う場合に備えて、ここに投稿しています。

#set($keys = [])
#foreach($key in $input.params().querystring.keySet())
  #set($success = $keys.add($key))
#end

#foreach($key in $input.params().headers.keySet())
  #if(!$keys.contains($key))
    #set($success = $keys.add($key))
  #end
#end

#foreach($key in $input.params().path.keySet())
  #if(!$keys.contains($key))
    #set($success = $keys.add($key))
  #end
#end

{
#foreach($key in $keys)
  "$key": "$util.escapeJavaScript($input.params($key))"#if($foreach.hasNext),#end
#end
}
24
BenV

あなたのラムダ関数にパラメータを渡すためには、API Gatewayリクエストとあなたのラムダ関数の間のマッピングを作成する必要があります。マッピングは、選択したAPI GatewayリソースのIntegration Request - > Mapping templatesセクションで行われます。

application/json型のマッピングを作成したら、右側でテンプレートを編集(鉛筆をクリック)します。

マッピングテンプレートは実際にはVelocityテンプレートで、そこではifs、loop、そしてもちろんそれに変数を表示することができます。テンプレートには 注入されたこれらの変数 があります。クエリ文字列パラメータ、リクエストヘッダなどに個別にアクセスできます。次のコードを使用すると、クエリ文字列全体を再作成できます。

{
    "querystring" : "#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0)&#end$util.urlEncode($key)=$util.urlEncode($input.params().querystring.get($key))#end",
    "body" : $input.json('$')
}

注意:チェック記号をクリックしてテンプレートを保存します。あなたのリソースの "テスト"ボタンであなたの変更をテストすることができます。しかし、AWSコンソールでクエリ文字列パラメータをテストするには、リソースのMethod Requestセクションでパラメータ名を定義する必要があります。

注:Velocityテンプレート言語の詳細については Velocityユーザーガイド を参照してください。

次に、ラムダテンプレートで、クエリ文字列を解析するために次の操作を実行できます。

var query = require('querystring').parse(event.querystring)
// access parameters with query['foo'] or query.foo
21
gimenete

私自身の質問の1つに答える試みの一部として - ここ 、私はこのトリックに出会いました。

API Gatewayマッピングテンプレートで、以下を使用して、HTTPクライアントから送信されたとおりの完全なクエリ文字列を取得します。

{
    "querystring": "$input.params().querystring"
}

利点は、クエリ文字列内の事前定義されたマッピングキーのセットに自分自身を制限する必要がないということです。クエリ文字列内の任意のキーと値のペアをそのまま使用できます。

注: this によると、VTLテンプレートで使用可能になった変数として$input.params(x)のみがリストされています。内部が変更され、querystringが利用できなくなる可能性があります。

15
user3526

これで、マッピングを設定するのではなく、Lambdaの新しいプロキシ統合タイプを使用して標準の形式で完全なリクエストを自動的に取得できるようになります。

参照してください: http://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration -on-proxy-resource

11
Jack Kohn - AWS

GET/user?name = bob

{
    "name": "$input.params().querystring.get('name')"
}

GET/user/bob

{
    "name": "$input.params('name')"
}
4
Dmitry Grinko

ここでの答えの多くは素晴らしいです。しかし、私はもう少し簡単なものが欲しかった。私は無料で "Hello World"サンプルで動作するものが欲しかった。これは私が単純にクエリ文字列にマッチするリクエストボディを生成したいと思ったことを意味します。

{
#foreach($param in $input.params().querystring.keySet())
  "$param": "$util.escapeJavaScript($input.params().querystring.get($param))" #if($foreach.hasNext),#end
#end
}

一番上の答えは、実際のものを構築するときにより便利なものを生み出すと思いますが、AWSのテンプレートを使用してhello worldをすばやく実行するには、これは非常に便利です。

4
KrisTC

次のパラメータマッピングの例では、パス、クエリ文字列、およびヘッダを含むすべてのパラメータを、JSONペイロードを介して統合エンドポイントに渡します。

#set($allParams = $input.params())
{
  "params" : {
    #foreach($type in $allParams.keySet())
    #set($params = $allParams.get($type))
    "$type" : {
      #foreach($paramName in $params.keySet())
      "$paramName" : "$util.escapeJavaScript($params.get($paramName))"
      #if($foreach.hasNext),#end
      #end
    }
    #if($foreach.hasNext),#end
    #end
  }
}

実際、このマッピングテンプレートは、次のようにペイロード内のすべての要求パラメータを出力します。

{
  "parameters" : {
     "path" : {    
       "path_name" : "path_value", 
       ...
     }
     "header" : {  
       "header_name" : "header_value",
       ...
     }
     'querystring" : {
       "querystring_name" : "querystring_value",
       ...
     }
   }
}

Amazon API Gateway開発者ガイドからコピー

4
matsev

クエリ文字列は、ラムダのjavascriptで解析するのが簡単です。

gET/user?name = bobの場合

 var name = event.params.querystring.name;

しかしこれはGET user/bobの質問を解決するものではありません。

2
Michael Riecken

Lambda関数はJSON入力を想定しているため、クエリ文字列の解析が必要です。解決策は、マッピングテンプレートを使用してクエリ文字列をJSONに変更することです。
C#.NET Coreに使用したので、予想される入力は "queryStringParameters"パラメーターを持つJSONである必要があります。
これを達成するには、以下の4つのステップに従ってください。

  1. API Gatewayリソースのマッピングテンプレートを開き、新しいapplication/json content-tyapを追加します。

API Gateway mapping template

  1. 以下のテンプレートをコピーして、クエリ文字列を解析してJSONにし、それをマッピングテンプレートに貼り付けます。

    {
    "queryStringParameters": {#foreach($key in $input.params().querystring.keySet())#if($foreach.index > 0),#end"$key":"$input.params().querystring.get($key)"#end}
    }
    
  2. API Gatewayで、Lambda関数を呼び出して、次のクエリ文字列を追加します(例)。param1=111&param2=222&param3=333

  3. マッピングテンプレートは以下のJSON出力を作成するはずです。 入力 あなたのLambda関数のために。

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. これで終わりです。これ以降、Lambda関数のロジックはクエリ文字列パラメータを使用できます。
    がんばろう!

1
Lior Kirshner

@ Jonathanの回答として、 Lambda Proxyの統合を使用します in Integration Request を使用して、ソースコードに次の形式でパスすることで実装する必要があります 502 Bad Gateway error。

NodeJS 8.10:

exports.handler = async (event, context, callback) => {
  // TODO: You could get path, parameter, headers, body value from this
  const { path, queryStringParameters, headers, body } = event;

  const response = {
    "statusCode": 200,
    "headers": {
      "Content-Type": "application/json"
    },
    "body": JSON.stringify({
      path, 
      query: queryStringParameters,
      headers,
      body: JSON.parse(body)
    }),
    "isBase64Encoded": false
  };

  return response;
};

APIを再実行する前に、 resource をAPI Gatewayにデプロイすることを忘れないでください。レスポンスJSONは body のどのセットが正しいかを返すだけです。そのため、イベントからパス、パラメータ、ヘッダ、ボディ値を取得できます。

const {パス、queryStringParameters、ヘッダー、本体} =イベント。

0
Long Nguyen

"Lambda Proxy Integration" のようにLambdaを使用できます。[ https://docs.aws.Amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-このlambdaのために利用可能なオプションは、lambda.htmlのためのシンプルなプロキシ#api-gateway-proxy-integration-lambda-function-python] です。

Nodejs Lambdaの 'event.headers'、 'event.pathParameters'、 'event.body'、 'event.stageVariables'、および 'event.requestContext'

Python Lambdaイベント['headers'] ['parametername']などの場合

0
RajDev