我正在尝试使用API Gateway,Lambda和RDS构建API。因此,您键入URL并以JSON格式从RDS获取特定行。
所以这就是我想要实现的目标。
我遇到的主要问题是我目前无法显示所有行,因为我总是要定义id,否则会发生错误。
我的API网关正文映射模板:
{
"table" : "$input.params('table')",
"id" : $input.params('id')
}
我的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);
});
});
};
如果您需要更多信息,请发表评论。
谢谢!
答案 0 :(得分:0)
我相信您的问题可能是您的if (id !== null)
声明。我嘲笑了你的例子,添加了console.log(sql);
并发现即使请求中没有发送id,返回的SQL查询也是SELECT * FROM '\"Customer\"' WHERE id = NULL
。
我将你的if语句更改为以下内容。
if (id) {
var sql = "SELECT * FROM ?? WHERE id = ?";
var inserts = [table, id];
} else {
var sql = "SELECT * FROM ?";
var inserts = table;
}
进行此更改后,如果请求中没有ID,则SQL查询为SELECT * FROM '\"Customer\"'
。
为了完整起见,我做了另一个修改。我根本没有使用Body Mapping Template。我使用了Integration Request配置中的“Use Lambda Proxy Integration”设置。这将消除使用Body Mapping模板的需要。
在方法请求配置中,定义URL查询字符串参数
在您的Lambda函数中,您将能够分别以event.queryStringParameters.table
和event.queryStringParameters.id
访问您的表格和ID。然后在Lambda函数中执行您想要的任何操作。
var table = JSON.stringify(event.queryStringParameters.table);
var id = JSON.stringify(event.queryStringParameters.id);
console.log("Table: " + table);
console.log("ID: " +id);
----------- EDITED ---------------
确保Lambda函数中的回调发送一个可由API网关处理的有效响应。这是我如何格式化我模拟的示例代码来测试它。
var response = {
"statusCode": 200,
"headers": {
"my_header": "my_value"
},
"body": JSON.stringify(results),
"isBase64Encoded": false
};
callback(null, response);
希望这有帮助。
答案 1 :(得分:0)
我认为你的映射模板可能太简单了。如果你让它工作,我很想知道如何,因为我的模板需要大量的代码,并且很难做到正确,但我接受了它。我认为如果没有更多的处理,你可能会遇到某些值时的其他问题或者放入你的参数。你将不得不处理逃避等等。
这是我用来将API网关映射到lambda的模板。我把它从我的cloudformation模板中拉出来,如果随机的json或额外的引号仍然存在,请原谅我。如果您更愿意看到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\
}
}
答案 2 :(得分:0)
首先,非常感谢大家的帮助。我自己修好了,但如果有人有类似的问题,我也会记录下来。
<强>&GT; API网关&lt;
转到集成请求
添加以下正文映射模板
{
#set($queryMap = $input.params().querystring)
#foreach( $key in $queryMap.keySet())
"$key" : "$queryMap.get($key)"
#if($foreach.hasNext),#end
#end
}
转到方法请求
<强>&GT; Lambda&lt;
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);
});
});
};
我认为,它可能不是lambda中最好的代码,但现在可以使用。我稍后会改进它。 :D
答案 3 :(得分:0)
您应将if-else
语句更改为:
if (id !== "") {
var sql = "SELECT * FROM ?? WHERE id = ?";
var inserts = [table, id];
} else {
var sql = "SELECT * FROM ?";
var inserts = table;
}
由于已经设置了主体映射模板,因此如果不将其传递为参数,则id
将被设置为""
。您可以在日志中查看其值,也可以尝试在输入id
语句之前记录if-else
。