[英]Serverless framework + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = Can't make POST Request Work
Ok, I'm on this problem since a few days. 好的,几天以来我一直在解决这个问题。
I try to take this tutorial : https://serverless.com/blog/make-serverless-graphql-api-using-lambda-dynamodb/ 我尝试学习本教程: https : //serverless.com/blog/make-serverless-graphql-api-using-lambda-dynamodb/
And make it work with apollo-server-lambda. 并使其与apollo-server-lambda一起使用。 This tutorial help: 本教程帮助:
https://medium.com/vessels/apollo-server-serverless-graphql-bliss-68e8e15195ac https://medium.com/vessels/apollo-server-serverless-graphql-bliss-68e8e15195ac
The problem is that nothing is working (for me) when you tried to use apollo server lambda with a real connection with DynamoDB. 问题是,当您尝试将apollo服务器lambda与DynamoDB进行真正的连接时,对我来说,什么都不起作用。 I got a list of errors that i can't remember anymore, it's just discouraging. 我得到了一个我已经不记得的错误列表了,这只是令人沮丧。
Here my code : 这是我的代码:
# 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
And my handler: 而我的经理:
# 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);
};
I tried to used Apollo 1 and 2, nothing work. 我尝试使用Apollo 1和2,没有任何作用。 I'm back to the version 1 since there is more forum posts about it. 我回到了版本1,因为有更多关于它的论坛帖子。 Mostly I have "internal server error". 通常,我有“内部服务器错误”。 I tried differents versions of server that i found on apollo docs but all my request failed, with curl on a terminal or directly on the API Gateway on AWS to test the function. 我尝试了在apollo文档中找到的不同版本的服务器,但是所有请求都失败了,在终端上或直接在AWS的API网关上进行curl测试功能。 I write the request body following this doc: https://www.apollographql.com/docs/apollo-server/requests.html 我根据此文档编写了请求正文: https : //www.apollographql.com/docs/apollo-server/requests.html
Here my cloudwatch log: 这是我的cloudwatch日志:
(node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): SyntaxError: Unexpected token = in JSON at position 8
Any help would be greatly appreciate !! 任何帮助将不胜感激!
Ok I figured out the problem. 好的,我知道了问题所在。 When you use the put function, you can't get the new item that you just insert in dynamoDB. 使用put函数时,无法获得仅插入dynamoDB中的新项。 You have to put "ReturnValues: 'ALL_OLD'" in your params object (first argument of the put function), like that no error is thrown, and you supposed to return the values you want since you just entered them in the db. 您必须将“ ReturnValues:'ALL_OLD'”放入params对象(put函数的第一个参数)中,就像不会引发任何错误一样,由于您刚刚在数据库中输入了值,因此您应该返回所需的值。
More details here: 此处有更多详细信息:
https://github.com/aws/aws-sdk-js/issues/803 https://github.com/aws/aws-sdk-js/issues/803
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.