【问题标题】:Serverless framework + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = Can't make POST Request Work无服务器框架 + AWS + Lambda + DynamoDB + GraphQL + Apollo Server = 无法使 POST 请求工作
【发布时间】: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 测试功能。我不知道我比以前有什么变化......如果我明白为什么以及如何,我会在这里发布我的解决方案!

标签: amazon-web-services aws-lambda graphql serverless-framework apollo-server


【解决方案1】:

好的,我找到了问题所在。使用 put 函数时,无法获取刚刚插入到 dynamoDB 中的新项目。您必须将“ReturnValues:'ALL_OLD'”放入您的 params 对象(put 函数的第一个参数)中,这样不会引发错误,并且您应该返回您想要的值,因为您刚刚在数据库中输入了它们。

更多细节在这里:

https://github.com/aws/aws-sdk-js/issues/803

【讨论】:

    猜你喜欢
    • 2021-06-03
    • 2021-01-30
    • 2020-04-15
    • 2021-11-02
    • 2016-05-17
    • 2022-07-27
    • 2017-05-24
    • 2017-11-20
    • 1970-01-01
    相关资源
    最近更新 更多