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


348

たとえば、使用したい場合

GET /user?name=bob

または

GET /user/bob

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

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

  • method.request.path.parameter-nameparameter-name「メソッドリクエスト」ページで定義された名前のパスパラメーターの場合。
  • method.request.querystring.parameter-nameparameter-nameメソッドリクエストページで定義された名前のクエリ文字列パラメータ用。

クエリ文字列を定義したにもかかわらず、これらのオプションのいずれも表示されません。

回答:


299

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']

23
これは素晴らしいヒントです。ただし、Lambdaプロキシ統合をオンにすると、「不正なLambdaプロキシ応答」エラーが発生する可能性があることに注意してください。ここではそれを修正する方法は次のとおりです。stackoverflow.com/questions/43708017/...
AaronBaker

5
実装がRequestHandler提供する透過的な逆シリアル化を維持しながら、Javaでこれを行う方法はありますか?

2
この設定はどこですか?
red888 2018年

2
@MattWestlake API Gatewayで、userというリソースを作成し、その下に{name}というリソースを作成します。
ジョナサン

3
この変更の後、Amazon API Gateway-> Actions-> Deploy APIに移動して、ライブ環境に再デプロイする必要があったことも述べておきます。
victorvartan

221

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

API Gatewayコンソール内...

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

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


9
ルートが/ user / {username}である/ user / bobのようなURLのURLパラメーターを介してこれを送信したことがありますか?私はあらゆる種類の順列を試しましたが、それをうまく行うことができませんでした。
Lucas

5
公式文書があるかどうか誰かが知っていますか?すべてのクエリパラメーターを単に渡すか、空の文字列よりも適切にオプションの値を処理することをお
勧めし

6
iOS開発者のための1つのヒント:各変数をクエリ文字列(「メソッドリクエスト」の下)として定義し、APIをデプロイするまで、API Gatewayはクエリデータを渡しません。デプロイまではコンソールテストで機能しますが、アプリのクエリからは削除されます。
AlexeyVMP 2015


6
ルーカス、/ user / {username}パターンを使用して動作させました。GETリソースパスが/ user / {username}である場合は、ステップ4で入力マッピングは次のようになります{"name": "$ input.params( 'username')"}
Gerard

134

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

使用できるマッピングテンプレートは次のとおりです。

{
  "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
  }  
}

すごい!ハンドラーに一般的に物事を渡すのに苦労していました。ここでベストアンサー。
Venkat D.

私はこれをしましたが、まだ何も得ていません。その未定義を示しています。URLでパラメーターを送信するにはどうすればよいですか?そして、通常のGET URLシナリオのように、URLに変数名を指定する必要がありますか?これで私を助けてください。
Parthapratim Neog 16

8
気にしないで結果を得た。問題は、マッピングを追加して保存しただけで、deployAPIを再度使用しなかったことです。新しいマッピングでAPIをデプロイすると、問題なく動作しました。トンありがとう。
Parthapratim Neog 16

@ shashu10私の答えを見てください
matsev

1
私はあなたのブログがどれほど役に立つかをあなたに言うことを始めることができません。「eturn-html-from-aws-api-gateway」の投稿を最初に見つけてフォローしました。それがまさに私が必要とするものだからです。ここで、関数にいくつかのパラメーターを渡し、それに基づいてhtmlを変更する必要があります-そして、あなたは本当のガイドを持つ唯一のものです!私が見つけた他のすべてのガイドは要点を見逃しているようです。
user3685427

41

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

APIの場合は、リソース名をクリックしてから取得します

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

入力する

application / json

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

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

選択する

メソッドリクエストパススルー

ここに画像の説明を入力してください

次に[保存]をクリックします

変数にアクセスするには、次の構文(これは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'])

そのため、必要な各変数に明示的に名前を付けたりマップしたりする必要はありません。


優秀な!機能はサービス内にありますが、見逃していました!
hnvasa

25

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

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

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

{
    "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

9
これが最良の解決策です。そのActions>Deploy APIときは忘れずに行ってください(これを忘れて時間を無駄にしました...)。関連付けられたラムダarnは、デプロイ直後に変更されます。で確認できStages > #stage (like: prod) > Deployment Historyます。
loretoparisi 2016年

24

受け入れられた答えは私にとってはうまくいきましたが、gimeneteの答えを拡張して、すべてのクエリ/パス/ヘッダーパラメーターを渡すために使用できる汎用テンプレートが必要でした(今のところ、文字列と同じ)、次のテンプレートが思い付きました。誰かが便利だと思った場合に備えて、ここに投稿します。

#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
}

1
Fabさん、POST(JSON本文あり)リクエストとクエリ文字列付きのGETの両方に同じ関数を使用できるようにしたいと思いました。夢を実現します。ありがとう!
Matt Fletcher、

@benvこれは完全なテンプレートですか?
nxmohamad

17

私自身の質問の1つにここで答えようとする一環として、このトリックに出くわしました。

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

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

利点は、クエリ文字列内の定義済みのマップされたキーのセットに制限する必要がないことです。これで、処理したい場合は、クエリ文字列で任意のキーと値のペアを受け入れることができます。

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


1
これは2017年5月時点でも機能しますが、実際のクエリ文字列ではなく、API Gatewayが作成するJSオブジェクトを返します。繰り返し文字列を配列に変換するためにクエリ文字列を解析しようとしているので、これは私にとって迷惑です。
トムサリーバ2017年

11

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

参照:http : //docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-set-up-simple-proxy.html#api-gateway-set-up-lambda-proxy-integration-on-プロキシリソース


1
理由はわかりませんが、プロキシ統合は通常は機能しません。作成した最新のAPIから削除する必要がありました。
Gustavo Straube 2016

同じ^さらに、API GatewayでCORSの問題がありました。AWSのドキュメントに従って、CORSを機能させることができませんでした。しかし、手動でCORSを設定する方法があり、機能する2015年半ばから後半の古いMediumの記事を見つけました。
Stephen Tetreault 2016年


5

ここでの答えの多くは素晴らしいです。しかし、もう少しシンプルなものが欲しかった。「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

次のパラメーターマッピングの例では、パス、クエリ文字列、ヘッダーを含むすべてのパラメーターを、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開発者ガイドからコピー


2

クエリ文字列はラムダのJavaScriptで解析するのは簡単です

GET / user?name = bobの場合

 var name = event.params.querystring.name;

ただし、これはGETユーザー/ボブの質問を解決しません。


そのevent.queryStringParameters.name
Neo

私がしなければならなかったevent.queryStringParameters.name
アンダースキットソン

2

@Jonathanの答えとして、「統合リクエストLambdaプロキシ統合使用する」のマークを付けた後、ソースコードで以下の形式で実装し、502 Bad Gatewayをパスする必要がありますエラーます。

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を再実行する前に、API Gatewayにリソースをデプロイすることを忘れないでください。応答JSON は、本文に設定されている正しいセットを返すだけです。したがって、イベントからパス、パラメーター、ヘッダー、本文の値を取得できます

const {path、queryStringParameters、headers、body} = event;


1

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

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

API Gatewayマッピングテンプレート

  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. マッピングテンプレートは、Lambda関数の入力である以下のJSON出力を作成する必要があります

    {
    "queryStringParameters": {"param3":"333","param1":"111","param2":"222"}
    }
    
  4. 完了です。この時点から、Lambda関数のロジックはクエリ文字列パラメーターを使用できます。
    幸運を!


0

Lambdaを「Lambdaプロキシ統合」として使用できます。これを参照してください [ https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-create-api-as-simple-proxy-for-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']などの場合



-1

これらの回答のいくつかを読んだ後、2018年8月にいくつかの組み合わせを使用して、Python 3.6のラムダを通じてクエリ文字列paramsを取得しました。

まず、API Gateway-> My API->リソース(左側)-> Integration Requestに行きました。下部にある[マッピングテンプレート]を選択し、コンテンツタイプとして次のように入力しますapplication/jsonます。

次に、Amazonが提供するメソッドリクエストパススルーテンプレートを選択し、APIの保存とデプロイを選択します。

次に、ラムダevent['params']はすべてのパラメーターにアクセスする方法です。クエリ文字列の場合:event['params']['querystring']

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.