无服务器框架 + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = 无法使 POST 请求工作
Posted
技术标签:
【中文标题】无服务器框架 + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = 无法使 POST 请求工作【英文标题】:Serverless framework + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = Can't make POST Request Work 【发布时间】:2018-12-13 18:29:08 【问题描述】:好的,我这几天一直在处理这个问题。
我尝试学习本教程: https://serverless.com/blog/make-serverless-graphql-api-using-lambda-dynamodb/
让它与 apollo-server-lambda 一起工作。本教程帮助:
https://medium.com/vessels/apollo-server-serverless-graphql-bliss-68e8e15195ac
问题是,当您尝试使用 apollo 服务器 lambda 与 DynamoDB 真正连接时,没有任何效果(对我而言)。我得到了一个我不记得的错误列表,这只是令人沮丧。
这是我的代码:
# serverless.yml
service: graphql-api
provider:
name: aws
runtime: nodejs6.10
region: eu-west-3
stage: dev
environment:
DYNAMODB_TABLE: $self:service-$self:provider.stage
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:GetItem
- dynamodb:UpdateItem
Resource: "arn:aws:dynamodb:$opt:region, self:provider.region:*:table/$self:provider.environment.DYNAMODB_TABLE"
resources:
Resources:
NicknamesTable:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
- AttributeName: firstName
AttributeType: S
KeySchema:
- AttributeName: firstName
KeyType: HASH
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: $self:provider.environment.DYNAMODB_TABLE
functions:
graphql:
handler: handler.graphql
events:
- http:
path: graphql
method: post
cors: true
- http:
path: graphql
method: get
cors: true
还有我的处理程序:
# handler.js
const AWS = require('aws-sdk');
const server = require("apollo-server-lambda");
const makeExecutableSchema = require('graphql-tools').makeExecutableSchema;
const dynamoDb = new AWS.DynamoDB.DocumentClient();
const promisify = foo => new Promise((resolve, reject) =>
foo((error, result) =>
if (error)
reject(error)
else
resolve(result)
)
)
const getGreeting = firstName => promisify(callback =>
dynamoDb.get(
TableName: process.env.DYNAMODB_TABLE,
Key: firstName ,
, callback))
.then(result =>
if (!result.Item)
return firstName
return result.Item.nickname
)
.then(name => `Hello, $name.`)
// add method for updates
const changeNickname = (firstName, nickname) => promisify(callback =>
dynamoDb.update(
TableName: process.env.DYNAMODB_TABLE,
Key: firstName ,
UpdateExpression: 'SET nickname = :nickname',
ExpressionAttributeValues:
':nickname': nickname
, callback))
.then(() => nickname)
const typeDefs = `
type Query
greeting(firstName: String!): String
type Mutation
changeNickname(
firstName: String!
nickname: String!
): String
`;
const resolvers =
Query:
greeting: (_, firstName ) => getGreeting(firstName),
,
Mutation:
changeNickname: (_, firstName, nickname ) => changeNickname(firstName, nickname),
;
exports.graphql = function (event, context, callback)
const callbackFilter = function (error, output)
output.headers = output.header || ;
output.headers['Access-Control-Allow-Origin'] = '*';
callback(error, output);
;
const handler = server.graphqlLambda( schema: makeExecutableSchema( typeDefs, resolvers ) );
return handler(event, context, callbackFilter);
;
我尝试使用 Apollo 1 和 2,但没有任何效果。我回到了版本 1,因为有更多关于它的论坛帖子。大多数情况下我有“内部服务器错误”。我尝试了在 apollo docs 上找到的不同版本的服务器,但我的所有请求都失败了,在终端上 curl 或直接在 AWS 上的 API Gateway 上测试该功能。我在此文档之后编写请求正文:https://www.apollographql.com/docs/apollo-server/requests.html
这里是我的 cloudwatch 日志:
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): SyntaxError: Unexpected token = in JSON at position 8
任何帮助将不胜感激!
【问题讨论】:
我使用 POST 的 lambdas 也有问题。亚马逊强制我在请求中添加一个随机查询参数:/myPOSTendpoint?blah=123 你可以添加一个查询参数吗? 我将我的 apollo 服务器改回了版本 2,最后我终于收到了一个请求 POST,以便在我的 aws 帐户上使用 API Gateway 测试功能。我不知道我比以前有什么变化......如果我明白为什么以及如何,我会在这里发布我的解决方案! 【参考方案1】:好的,我找到了问题所在。使用 put 函数时,无法获取刚刚插入到 dynamoDB 中的新项目。您必须将“ReturnValues:'ALL_OLD'”放入您的 params 对象(put 函数的第一个参数)中,这样不会引发错误,并且您应该返回您想要的值,因为您刚刚在数据库中输入了它们。
更多细节在这里:
https://github.com/aws/aws-sdk-js/issues/803
【讨论】:
以上是关于无服务器框架 + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = 无法使 POST 请求工作的主要内容,如果未能解决你的问题,请参考以下文章
AWS Lambda 上的 Nestjs(无服务器框架)|如何访问事件参数?
无服务器框架 + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = 无法使 POST 请求工作
使用 graphql、aws lambda 和无服务器框架的多个 url 路径选项错误
如何从 AWS Lambda 函数 + 无服务器框架的 URL 中删除阶段?
无服务器框架+ AWS + Lambda + DynamoDB + GraphQL + Apollo Server =无法使POST请求工作