apollo-server-lambda:无法根据事件确定事件源

Kri*_*sna 5 authorization http-headers graphql apollo-server

我正在为我的应用程序使用apollo-server-lambda。我已经创建了自定义授权 http 标头,这是必需的。如果authoization: LETMEIN那么它会返回 true 并返回所有数据,如果没有任何数据authoization或错误authoization则它将抛出错误。对于本地开发,我使用了serverless-offline。在本地环境中,它按预期工作,这是图像,但是当我将代码部署到 AWS 时,api 端不起作用。它总是向我抛出错误:这是链接

我测试我的功能 AWS 控制台。我收到此错误:

在此输入图像描述

我不明白我做错了什么。

这是我的代码

/* eslint-disable @typescript-eslint/no-var-requires */
import { ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core';
import { ApolloServer, AuthenticationError } from 'apollo-server-lambda';
import schema from '../graphql/schema';
import resolvers from '../resolvers';
import runWarm from '../utils/run-warm';

export const authToken = (token: string) => {
  if (token === 'LETMEIN') {
    return;
  } else {
    throw new AuthenticationError('No authorization header supplied');
  }
};

const server = new ApolloServer({
  typeDefs: schema,
  resolvers,
  debug: false,
  plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
  context: ({ event }) => {
    //console.log(context);

    if (event.headers) {
      authToken(event.headers.authorization);
    }
  },
});

export default runWarm(
  server.createHandler({
    expressGetMiddlewareOptions: {
      cors: {
        origin: '*',
        credentials: true,
        allowedHeaders: ['Content-Type', 'Origin', 'Accept'],
        optionsSuccessStatus: 200,
        maxAge: 200,
      },
    },
  })
);
Run Code Online (Sandbox Code Playgroud)
这是我的 Lambda 函数

/**
 * Running warm functions help prevent cold starts
 */
const runWarm =
  (lambdaFunc: AWSLambda.Handler): AWSLambda.Handler =>
  (event, context, callback) => {
    // Detect the keep-alive ping from CloudWatch and exit early. This keeps our
    // lambda function running hot.
    if (event.source === 'serverless-plugin-warmup') {
      return callback(null, 'pinged');
    }
    return lambdaFunc(event, context, callback);
  };

export default runWarm;
Run Code Online (Sandbox Code Playgroud)

小智 13

这不是直接答案,但可能会有所帮助,并且如果其他人(像我一样)由于使用 apollo-server-lambda 时出现“无法根据事件确定事件源”错误而发现此线程,则可能会很有用。

该错误来自apollo-server-lambda 正在使用的@vendia/serverless-express 。

在 serverless-express 的 src/event-sources/utils.js 中,有一个名为 getEventSourceNameBasedOnEvent() 的函数,该函数引发错误。它需要在事件对象中找到一些东西,经过一些实验,我发现像这样编写 lambda 函数解决了我的问题:

const getHandler = (event, context) => {
    const server = new ApolloServer({
        typeDefs,
        resolvers,
        debug: true,
    });
    const graphqlHandler = server.createHandler();
    if (!event.requestContext) {
        event.requestContext = context;
    }
    return graphqlHandler(event, context);
}

exports.handler = getHandler;
Run Code Online (Sandbox Code Playgroud)

请注意,上下文对象被添加到带有键“requestContext”的事件对象中......这就是修复。

(另请注意,我已在代码中的其他位置定义了 typeDefs 和解析器)

我不能保证这是理想的做法,但它确实对我有用。

  • 这对我的 Netlify 功能很有用。谢谢! (7认同)