简体   繁体   English

如何在Lambda / API网关中使用参数传递

[英]How to use param passing in Lambda / API Gateway

I am trying to build an API using API Gateway, Lambda, and RDS. 我正在尝试使用API​​网关,Lambda和RDS构建API。 So you type in the URL and get the specific rows from RDS back in a JSON format. 因此,您输入URL并以JSON格式从RDS获取特定行。

So this is what I would like to achieve. 这就是我想要实现的目标。

  • /production/myfootballapi?table=football -> all rows in the table should be returned (not working) / production / myfootballapi?table = football->应该返回表中的所有行(不起作用)
  • /production/myfootballapi?table=football&id=2 -> only the id 2 row should be returned (only this case works) / production / myfootballapi?table = football&id = 2->仅返回id 2行(仅在这种情况下有效)

The main problem that I am having is that I currently can't show all rows because I always have to define the id otherwise an error occurs. 我遇到的主要问题是我目前无法显示所有行,因为我总是必须定义id,否则会发生错误。

My API Gateway Body Mapping Template: 我的API网关正文映射模板:

{
"table" : "$input.params('table')",
"id" : $input.params('id')
}

My Lambda function 我的Lambda函数

var mysql = require('mysql2');
var config = require('./config.json');

var pool  = mysql.createPool({
host     : config.dbhost,
user     : config.dbuser,
password : config.dbpassword,
database : config.dbname,
});


exports.handler =  (event, context, callback) => {


//prevent timeout from waiting event loop
context.callbackWaitsForEmptyEventLoop = false;

pool.getConnection(function(err, connection) {
if (err) throw err; 
// Use the connection

var table = event.table;
var id = event.id;

// This if-function is just a try to solve this problem but it doesn't work
if (id !== null) { 
  var sql = "SELECT * FROM ?? WHERE id = ?";
  var inserts = [table, id];

} else {
  var sql = "SELECT * FROM ?";
  var inserts = table;
}

sql = mysql.format(sql, inserts);

connection.query(sql, function (error, results, fields) {
  // And done with the connection.
  connection.release();
  // Handle error after the release.
  if (error) callback(error);
  else callback(null,results);
  });
});
};

If you need further information, please leave a comment. 如果您需要更多信息,请发表评论。

THANKS! 谢谢!

I believe your problem may be your if (id !== null) statement. 我相信您的问题可能是您的if (id !== null)语句。 I mocked up your example, added console.log(sql); 我模拟了您的示例,添加了console.log(sql); and found that even when no id was sent in the request, the SQL query returned was SELECT * FROM '\\"Customer\\"' WHERE id = NULL . 并发现,即使在请求中未发送ID时,返回的SQL查询也是SELECT * FROM '\\"Customer\\"' WHERE id = NULL

I changed your if statement to the following. 我将您的if语句更改为以下内容。

 if (id) { var sql = "SELECT * FROM ?? WHERE id = ?"; var inserts = [table, id]; } else { var sql = "SELECT * FROM ?"; var inserts = table; } 

After making this change, the SQL query was SELECT * FROM '\\"Customer\\"' as expected when no ID is in the request. 进行此更改后,当请求中没有ID时,SQL查询将按预期执行SELECT * FROM '\\"Customer\\"'

For completeness, I did make one other modification. 为了完整起见,我做了另一处修改。 I did not use the Body Mapping Template at all. 我根本没有使用身体贴图模板。 I used the "Use Lambda Proxy Integration" setting in the Integration Request configuration instead. 我在集成请求配置中使用了“使用Lambda代理集成”设置。 This will eliminate the need to use Body Mapping Templates. 这将消除使用人体贴图模板的需要。

在此处输入图片说明

In the Method Request configuration, define the URL Query String Parameters 在“方法请求”配置中,定义URL查询字符串参数

在此处输入图片说明

In your Lambda function, you will be able to access your table and id as event.queryStringParameters.table and event.queryStringParameters.id respectively. 在Lambda函数中,您将能够分别以event.queryStringParameters.tableevent.queryStringParameters.id访问表和id。 Then perform whatever actions you want in your Lambda function. 然后在Lambda函数中执行所需的任何操作。

 var table = JSON.stringify(event.queryStringParameters.table); var id = JSON.stringify(event.queryStringParameters.id); console.log("Table: " + table); console.log("ID: " +id); 

----------- EDITED --------------- -----------编辑---------------

Make sure your callback in your Lambda function sends a valid response that can be handled by the API gateway. 确保您的Lambda函数中的回调发送了可以由API网关处理的有效响应。 Here is how I formatted my sample code that I mocked up to test this. 这是我格式化为进行测试的示例代码的格式。

 var response = { "statusCode": 200, "headers": { "my_header": "my_value" }, "body": JSON.stringify(results), "isBase64Encoded": false }; callback(null, response); 

Hope this helps. 希望这可以帮助。

I think your mapping template is probably too simple. 我认为您的映射模板可能太简单了。 If you get that to work I'd love to know how because my template requires a great deal of code and it was a pain to get right but I've accepted it. 如果您能做到这一点,我很想知道如何做,因为我的模板需要大量的代码,并且正确无误,但我已经接受了。 I think without more processing you'll probably run into other issues when certain values or put into your parameters. 我认为,如果不进行更多处理,当您将某些值或参数放入某些值时,您可能会遇到其他问题。 You'll have to deal with escaping etc etc. 您必须处理转义等问题。

This is the template I use to map API gateway to lambda. 这是我用来将API网关映射到lambda的模板。 I pulled it out of my cloudformation template so forgive me if random json or extra quotes are still present. 我将其从cloudformation模板中拉出,因此如果仍然存在随机json或额外的引号,请原谅我。 If you rather see the cloudformation template I can show that. 如果您宁愿看到cloudformation模板,我可以显示出来。

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

First of all, many thanks to everyone for helping me. 首先,非常感谢大家的帮助。 I fixed it myself but I will also document this if someone has a similar question. 我自己修复了这个问题,但是如果有人有类似的问题,我也会记录下来。

> API Gateway < > API网关<

Go to Integration Request 转到集成请求

转到集成请求

Add the following Body Mapping Template 添加以下人体贴图模板

在此处输入图片说明

{
#set($queryMap = $input.params().querystring)

#foreach( $key in $queryMap.keySet())
  "$key" : "$queryMap.get($key)"
  #if($foreach.hasNext),#end
#end
}

Go to Method Request 转到方法请求

在此处输入图片说明

Add the parameters 添加参数 在此处输入图片说明

> Lambda < > Lambda <

var mysql = require('mysql2');
var config = require('./config.json');

var pool  = mysql.createPool({
    host     : config.dbhost,
    user     : config.dbuser,
    password : config.dbpassword,
    database : config.dbname,
  });


exports.handler =  (event, context, callback) => {

  //prevent timeout from waiting event loop
  context.callbackWaitsForEmptyEventLoop = false;

  pool.getConnection(function(err, connection) {
    if (err) throw err; 
    // Use the connection

   var table = event.table;
   var id = event.id;

    if (isNaN(id)) { 
       var sql = "SELECT * FROM ??";
       var inserts = table;
     } else {
       var sql = "SELECT * FROM ?? WHERE id = ?";
       var inserts = [table, id];
     }

    sql = mysql.format(sql, inserts);

  connection.query(sql, function (error, results, fields) {
      // And done with the connection.
      connection.release();
      // Handle error after the release.
      if (error) callback(error);
      else callback(null,results);
    });
  });
};

Source: https://aws.amazon.com/de/blogs/compute/using-api-gateway-mapping-templates-to-handle-changes-in-your-back-end-apis/ 来源: https//aws.amazon.com/de/blogs/compute/using-api-gateway-mapping-templates-to-handle-changes-in-your-back-end-apis/

I think, it is probably not the best code in lambda but it works for now. 我认为,这可能不是lambda中最好的代码,但目前可以使用。 I will improve it later. 我稍后会改善。 :D :D

You should change the if-else statement to : 您应该将if-else语句更改为:

if (id !== "") { 
  var sql = "SELECT * FROM ?? WHERE id = ?";
  var inserts = [table, id];
} else {
  var sql = "SELECT * FROM ?";
  var inserts = table;
}

Since you have set the body mapping template the id will be set to "" when you don't pass it as parameter. 由于您已经设置了人体贴图模板,因此当您不将其作为参数传递时,其id将设置为"" You can see its value in logs or you can try to log the id before you enter the if-else statement. 您可以在日志中查看其值,也可以尝试在输入if-else语句之前记录id

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM