1

我正在练习 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",
  ]
}

4

1 回答 1

1

正如您所观察到的,它./src/graphql/schema.graphql并没有被打包到最终的工件无服务器构建和部署中。

您可以通过将属性指定到您的函数来添加它:

graphql:
  handler: src/handlers/graphql.default
  events:
    - http:
        path: ${env:api_prefix}/graphql
        method: any
        cors: true
  package:
    include:
      - src/graphql/schema.graphql

来源:https ://www.serverless.com/framework/docs/providers/aws/guide/packaging#patterns

于 2021-12-16T17:59:29.820 回答