我正在尝试在本地系统中创建一个应用程序,然后使用SAM CLI将其部署到AWS云。该应用程序的基本轮廓在图中给出。
我为此应用程序创建了一个名为 myproj 的目录,所有子文件夹和文件如下图所示。
template.yaml 文件包含以下代码-
AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Resources:
myDB:
Type: AWS::Serverless::SimpleTable
Properties:
TableName: tabmine
PrimaryKey:
Name: id
Type: String
ProvisionedThroughput:
ReadCapacityUnits: 5
WriteCapacityUnits: 5
LambdaWrite:
Type: AWS::Serverless::Function
Properties:
CodeUri: functionWrite/
Handler: write.handler
Runtime: nodejs12.x
Events:
apiForLambda:
Type: Api
Properties:
Path: /writedb
Method: post
Policies:
DynamoDBWritePolicy:
TableName: !Ref myDB
LambdaRead:
Type: AWS::Serverless::Function
Properties:
CodeUri: functionRead/
Handler: read.handler
Runtime: nodejs12.x
Events:
apiForLambda:
Type: Api
Properties:
Path: /readdb
Method: post
Policies:
DynamoDBReadPolicy:
TableName: !Ref myDB
在 functionRead 文件夹中, package.json 具有以下内容-
{
"name": "myproj",
"version": "1.0.0",
"description": "",
"main": "read.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.783.0"
}
}
read.js 文件包含以下代码-
var AWS = require('aws-sdk');
var ddb = new AWS.DynamoDB.DocumentClient();
exports.handler = function(event, context, callback) {
var ID = event.id;
var params = {
TableName: 'tabmine',
Key: {
'id': ID
}
};
ddb.get(params, callback);
};
在 functionWrite 文件夹中,文件 package.json 具有以下内容-
{
"name": "myproj",
"version": "1.0.0",
"description": "",
"main": "write.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"aws-sdk": "^2.783.0"
}
}
文件 write.js 具有以下内容-
var AWS = require('aws-sdk');
var ddb = new AWS.DynamoDB.DocumentClient();
exports.handler = function(event, context, callback) {
var ID = event.id;
var NAME = event.name;
var params = {
TableName: 'tabmine',
Item: {
'id': ID,
'name': NAME
}
};
ddb.put(params, callback);
};
然后,我导航回终端中的 myproj 目录,并运行命令sam build
。
构建完成后,我运行命令sam deploy --guided
,并按照以下步骤将堆栈部署到云中。然后,我检查了控制台以确认部署是否成功。
然后,在终端中,我运行了 curl -X POST -d '{"id":"one","name":"john"}' https://0000000000.execute-api.ap-south-1.amazonaws.com/Prod/writedb
。但是我得到了{message : 'Internal server Error'}
。
要确认lambda和dynamoDB是否正确链接,我转到Lambda控制台并为名称为 write.js 的lambda函数创建了 test事件相同的有效负载{"id":"one","name":"john"}
。它成功运行,并将这两项输入到dyanmoDB表中。同样,我为lambda函数创建了另一个 test事件,其名称为 read.js ,其有效负载为{"id":"one"}
。它还成功运行并显示了数据。
要确认API网关和lambda是否正确链接,我在API网关中对资源/writedb
和/readdb
都进行了测试,但这给了{{1 }}。
请帮助我解决这个问题。
答案 0 :(得分:1)
来自API网关调用的事件对象将具有以下结构-
{
resource: '/func1',
path: '/func1',
httpMethod: 'POST',
headers: {
accept: '*/*',
'content-type': 'application/x-www-form-urlencoded',
Host: '0000000000.execute-api.ap-south-1.amazonaws.com',
'User-Agent': 'curl/7.71.1',
'X-Amzn-Trace-Id': 'Root=1-5fa018aa-60kdfkjsddd5f6c6c07a2',
'X-Forwarded-For': '178.287.187.178',
'X-Forwarded-Port': '443',
'X-Forwarded-Proto': 'https'
},
multiValueHeaders: {
accept: [ '*/*' ],
'content-type': [ 'application/x-www-form-urlencoded' ],
Host: [ '0000000000.execute-api.ap-south-1.amazonaws.com' ],
'User-Agent': [ 'curl/7.71.1' ],
'X-Amzn-Trace-Id': [ 'Root=1-5fa018aa-603d90fhgdhdgdjhj6c6dfda2' ],
'X-Forwarded-For': [ '178.287.187.178' ],
'X-Forwarded-Port': [ '443' ],
'X-Forwarded-Proto': [ 'https' ]
},
queryStringParameters: null,
multiValueQueryStringParameters: null,
pathParameters: null,
stageVariables: null,
requestContext: {
resourceId: 'scsu6k',
resourcePath: '/func1',
httpMethod: 'POST',
extendedRequestId: 'VYjfdkjkjfjkfuA=',
requestTime: '02/Nov/2020:14:33:14 +0000',
path: '/test/func1',
accountId: '00000000000',
protocol: 'HTTP/1.1',
stage: 'test',
domainPrefix: 'f8h785q05a',
requestTimeEpoch: 1604327594697,
requestId: '459e0256-9c6f-4a24-bcf2-05520d6bc58a',
identity: {
cognitoIdentityPoolId: null,
accountId: null,
cognitoIdentityId: null,
caller: null,
sourceIp: '178.287.187.178',
principalOrgId: null,
accessKey: null,
cognitoAuthenticationType: null,
cognitoAuthenticationProvider: null,
userArn: null,
userAgent: 'curl/7.71.1',
user: null
},
domainName: '000000000.execute-api.ap-south-1.amazonaws.com',
apiId: 'lkjfslkfj'
},
body: '{"id":"1","name":"John"}',
isBase64Encoded: false
}
在上面的JSON对象事件中,我们需要 body 。由于主体是字符串,因此我们需要将其转换为JSON对象。
因此,应将 write.js 修改为-
var AWS = require('aws-sdk');
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
exports.handler = async (event) => {
try {
//console.log(event);
//console.log(event.body);
var obj = JSON.parse(event.body);
//console.log(obj.id);
//console.log(obj.name);
var ID = obj.id;
var NAME = obj.name;
var params = {
TableName:'tabmine',
Item: {
id : {S: ID},
name : {S: NAME}
}
};
var data;
var msg;
try{
data = await ddb.putItem(params).promise();
console.log("Item entered successfully:", data);
msg = 'Item entered successfully';
} catch(err){
console.log("Error: ", err);
msg = err;
}
var response = {
'statusCode': 200,
'body': JSON.stringify({
message: msg
})
};
} catch (err) {
console.log(err);
return err;
}
return response;
};
类似地, read.js 将被修改为-
var AWS = require('aws-sdk');
var ddb = new AWS.DynamoDB({apiVersion: '2012-08-10'});
exports.handler = async (event) => {
try {
//console.log(event);
//console.log(event.body);
var obj = JSON.parse(event.body);
//console.log(obj.id);
//console.log(obj.name);
var ID = obj.id;
var params = {
TableName:'tabmine',
Key: {
id : {S: ID}
}
};
var data;
try{
data = await ddb.getItem(params).promise();
console.log("Item read successfully:", data);
} catch(err){
console.log("Error: ", err);
data = err;
}
var response = {
'statusCode': 200,
'body': JSON.stringify({
message: data
})
};
} catch (err) {
console.log(err);
return err;
}
return response;
};
因此,这将解决问题。并且 template.yaml 文件也是正确的。