无服务器框架和 DynamoDB:JSON.parse JSON 中的意外标记
Serverless Framework and DynamoDB: Unexpected token in JSON at JSON.parse
嗨,我按照这个 Serverless + AWS REST API tutorial 进行了,效果很好,我开始工作了。
现在,我正在尝试修改它,但在尝试将数据提交到 DynamoDB 时遇到了困难 table。
使用 Postman 提交有效的 JSON 对象,我收到了 502 响应。如果我在 Lambda 中测试函数,我会收到以下错误:
{
"errorType": "SyntaxError",
"errorMessage": "Unexpected token o in JSON at position 1",
"trace": [
"SyntaxError: Unexpected token o in JSON at position 1",
" at JSON.parse (<anonymous>)",
" at Runtime.module.exports.submit [as handler] (/var/task/api/interview.js:11:28)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)",
" at process._tickCallback (internal/process/next_tick.js:68:7)"
]
}
在搜索解决方案后,我发现作为 JSON.parse(event)
传递的 event
似乎未定义。
这是serverless.yml:
service: interview
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: us-east-1
environment:
INTERVIEW_TABLE: ${self:service}-${opt:stage, self:provider.stage}
INTERVIEW_EMAIL_TABLE: "interview-email-${opt:stage, self:provider.stage}"
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
Resource: "*"
resources:
Resources:
CandidatesDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
StreamSpecification:
StreamViewType: "NEW_AND_OLD_IMAGES"
TableName: ${self:provider.environment.INTERVIEW_TABLE}
functions:
interviewSubmission:
handler: api/interview.submit
memorySize: 128
description: Submit interview information and starts interview process.
events:
- http:
path: interviews
method: post
和interview.js
'use strict';
const uuid = require('uuid');
const AWS = require('aws-sdk');
AWS.config.setPromisesDependency(require('bluebird'));
const dynamoDb = new AWS.DynamoDB.DocumentClient();
module.exports.submit = (event, context, callback) => {
const requestBody = JSON.parse(event);
const fullname = requestBody.fullname;
const email = requestBody.email;
const test = requestBody.test;
const experience = requestBody.experience;
if (typeof fullname !== 'string' || typeof email !== 'string' || typeof experience !== 'number') {
console.error('Validation Failed');
callback(new Error('Couldn\'t submit interview because of validation errors.'));
return;
}
submitInterviewP(interviewInfo(fullname, email, experience, test))
.then(res => {
callback(null, {
statusCode: 200,
body: JSON.stringify({
message: `Sucessfully submitted interview with email ${email}`,
interviewId: res.id
})
});
})
.catch(err => {
console.log(err);
callback(null, {
statusCode: 500,
body: JSON.stringify({
message: `Unable to submit interview with email ${email}`
})
})
});
};
const submitInterviewP = interview => {
console.log('Submitting interview');
const interviewInfo = {
TableName: process.env.INTERVIEW_TABLE,
Item: interview,
};
return dynamoDb.put(interviewInfo).promise()
.then(res => interview);
};
const interviewInfo = (fullname, email, experience,test) => {
const timestamp = new Date().getTime();
return {
id: uuid.v1(),
fullname: fullname,
email: email,
experience: experience,
test: test,
submittedAt: timestamp,
updatedAt: timestamp,
};
};
如果我将 event
参数替换为有效的 JSON 对象,然后再次部署。我能够成功地将对象插入 dynamoDB。
有线索吗?如果有任何我遗漏的东西可以帮助,请告诉我。
谢谢!
API 网关将事件正文中的请求正文字符串化 属性。
目前您正在尝试解析事件对象 const requestBody = JSON.parse(event);
,这是错误的。您需要解析 event.body 属性:
const requestBody = JSON.parse(event.body);
嗨,我按照这个 Serverless + AWS REST API tutorial 进行了,效果很好,我开始工作了。
现在,我正在尝试修改它,但在尝试将数据提交到 DynamoDB 时遇到了困难 table。
使用 Postman 提交有效的 JSON 对象,我收到了 502 响应。如果我在 Lambda 中测试函数,我会收到以下错误:
{
"errorType": "SyntaxError",
"errorMessage": "Unexpected token o in JSON at position 1",
"trace": [
"SyntaxError: Unexpected token o in JSON at position 1",
" at JSON.parse (<anonymous>)",
" at Runtime.module.exports.submit [as handler] (/var/task/api/interview.js:11:28)",
" at Runtime.handleOnce (/var/runtime/Runtime.js:66:25)",
" at process._tickCallback (internal/process/next_tick.js:68:7)"
]
}
在搜索解决方案后,我发现作为 JSON.parse(event)
传递的 event
似乎未定义。
这是serverless.yml:
service: interview
frameworkVersion: ">=1.1.0 <2.0.0"
provider:
name: aws
runtime: nodejs10.x
stage: dev
region: us-east-1
environment:
INTERVIEW_TABLE: ${self:service}-${opt:stage, self:provider.stage}
INTERVIEW_EMAIL_TABLE: "interview-email-${opt:stage, self:provider.stage}"
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
Resource: "*"
resources:
Resources:
CandidatesDynamoDbTable:
Type: 'AWS::DynamoDB::Table'
DeletionPolicy: Retain
Properties:
AttributeDefinitions:
-
AttributeName: "id"
AttributeType: "S"
KeySchema:
-
AttributeName: "id"
KeyType: "HASH"
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
StreamSpecification:
StreamViewType: "NEW_AND_OLD_IMAGES"
TableName: ${self:provider.environment.INTERVIEW_TABLE}
functions:
interviewSubmission:
handler: api/interview.submit
memorySize: 128
description: Submit interview information and starts interview process.
events:
- http:
path: interviews
method: post
和interview.js
'use strict';
const uuid = require('uuid');
const AWS = require('aws-sdk');
AWS.config.setPromisesDependency(require('bluebird'));
const dynamoDb = new AWS.DynamoDB.DocumentClient();
module.exports.submit = (event, context, callback) => {
const requestBody = JSON.parse(event);
const fullname = requestBody.fullname;
const email = requestBody.email;
const test = requestBody.test;
const experience = requestBody.experience;
if (typeof fullname !== 'string' || typeof email !== 'string' || typeof experience !== 'number') {
console.error('Validation Failed');
callback(new Error('Couldn\'t submit interview because of validation errors.'));
return;
}
submitInterviewP(interviewInfo(fullname, email, experience, test))
.then(res => {
callback(null, {
statusCode: 200,
body: JSON.stringify({
message: `Sucessfully submitted interview with email ${email}`,
interviewId: res.id
})
});
})
.catch(err => {
console.log(err);
callback(null, {
statusCode: 500,
body: JSON.stringify({
message: `Unable to submit interview with email ${email}`
})
})
});
};
const submitInterviewP = interview => {
console.log('Submitting interview');
const interviewInfo = {
TableName: process.env.INTERVIEW_TABLE,
Item: interview,
};
return dynamoDb.put(interviewInfo).promise()
.then(res => interview);
};
const interviewInfo = (fullname, email, experience,test) => {
const timestamp = new Date().getTime();
return {
id: uuid.v1(),
fullname: fullname,
email: email,
experience: experience,
test: test,
submittedAt: timestamp,
updatedAt: timestamp,
};
};
如果我将 event
参数替换为有效的 JSON 对象,然后再次部署。我能够成功地将对象插入 dynamoDB。
有线索吗?如果有任何我遗漏的东西可以帮助,请告诉我。
谢谢!
API 网关将事件正文中的请求正文字符串化 属性。
目前您正在尝试解析事件对象 const requestBody = JSON.parse(event);
,这是错误的。您需要解析 event.body 属性:
const requestBody = JSON.parse(event.body);