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/
And make it work with apollo-server-lambda. This tutorial help:
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. 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. I'm back to the version 1 since there is more forum posts about it. 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. I write the request body following this doc: https://www.apollographql.com/docs/apollo-server/requests.html
Here my cloudwatch log:
(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. 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.
More details here:
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.