我正在练习 Graphql 和 AWS。我使用简单的无服务器框架也创建了简单的 Graphql 模式。我部署了架构(好像这个graphql.schema
文件没有部署),解析器到 AWS。它成功地创建了一个 DynamoDB 表和 lambda。我可以使用 serverless-offline 通过 Graphql Playground 发出 POST/GET 请求。但问题是 api 端点不起作用。它给我看internal server error
。我正在调查这个问题。从 cloud watch 我发现了我创建 Lambda 函数的本地模式并找到了graphql.schema
. 这是我得到的错误"ENOENT: no such file or directory, open './src/graphql/schema.graphql'".
这是 lambda 错误图像
这是我的 lambda 函数
import { ApolloServer } from 'apollo-server-lambda';
import { ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core';
import runWarm from '../utils/run-warm';
import fs from 'fs';
const schema = fs.readFileSync('./src/graphql/schema.graphql', 'utf8'); // This is local my schema
import resolvers from '../resolvers';
const server = new ApolloServer({
typeDefs: schema,
resolvers,
introspection: true,
plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
});
export default runWarm(
server.createHandler({
expressGetMiddlewareOptions: {
cors: {
origin: '*',
credentials: true,
allowedHeaders: ['Content-Type', 'Origin', 'Accept'],
optionsSuccessStatus: 200,
},
},
})
);
这是我的无服务器 YAML 文件
service: serverless-aws-graphql
package:
individually: true
provider:
name: aws
profile: ${env:profile}
runtime: nodejs14.x
stage: ${env:stage}
region: eu-north-1
timeout: 30
apiName: ${self:service.name}-${self:provider.stage}
environment:
ITEM_TABLE: ${self:service}-items-${self:provider.stage}
iamRoleStatements:
- Effect: Allow
Action:
- dynamodb:Query
- dynamodb:Scan
- dynamodb:GetItem
- dynamodb:PutItem
- dynamodb:UpdateItem
- dynamodb:DeleteItem
Resource: 'arn:aws:dynamodb:${opt:region, self:provider.region}:*:table/${self:provider.environment.ITEM_TABLE}'
apiGateway:
shouldStartNameWithService: true
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
packager: 'npm' # Packager that will be used to package your external modules
warmup:
enabled: true
events:
- schedule: rate(5 minutes)
prewarm: true
concurrency: 1
prune:
automatic: true
number: 5
functions:
graphql:
handler: src/handlers/graphql.default
events:
- http:
path: ${env:api_prefix}/graphql
method: any
cors: true
resources:
Resources:
ItemsTable:
Type: 'AWS::DynamoDB::Table'
Properties:
AttributeDefinitions:
- AttributeName: PK
AttributeType: S
- AttributeName: SK
AttributeType: S
- AttributeName: GSI1PK
AttributeType: S
- AttributeName: GSI1SK
AttributeType: S
KeySchema:
- AttributeName: PK
KeyType: HASH
- AttributeName: SK
KeyType: RANGE
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
GlobalSecondaryIndexes:
- IndexName: GSI1
KeySchema:
- AttributeName: GSI1PK
KeyType: HASH
- AttributeName: GSI1SK
KeyType: RANGE
Projection:
ProjectionType: ALL
ProvisionedThroughput:
ReadCapacityUnits: 1
WriteCapacityUnits: 1
TableName: ${self:provider.environment.ITEM_TABLE}
plugins:
- serverless-webpack
- serverless-offline
- serverless-plugin-warmup
- serverless-dotenv-plugin
- serverless-prune-plugin
这是我的 webpack.config.js 设置
const nodeExternals = require('webpack-node-externals');
const slsw = require('serverless-webpack');
module.exports = {
entry: slsw.lib.entries,
target: 'node',
mode: slsw.lib.webpack.isLocal ? 'development' : 'production',
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/,
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js', '.jsx'],
},
};
这是我的 tsconfig 设置
{
"compilerOptions": {
"target": "esnext",
"allowJs": true,
"skipLibCheck": false,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"noEmit": false,
"jsx": "preserve",
"noUnusedLocals": true,
"noUnusedParameters": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
]
}