serverless / serverless-graphql

Serverless GraphQL Examples for AWS AppSync and Apollo
https://www.serverless.com
MIT License
2.72k stars 364 forks source link

Serverless.yml for graphql-yoga with prisma #339

Open abelovic opened 6 years ago

abelovic commented 6 years ago

This is probably an easy question but I have been struggling to get this to work :(

Using this example:

https://github.com/graphcool/graphql-yoga/tree/master/examples/lambda

except trying to modify it so that it uses this boilerplate (or any of them really):

https://github.com/graphql-boilerplates/node-graphql-server/tree/master/advanced

I tried to modify the "function/(graphql & playground)/handler" in the serverless.yml file to point to src/index.js file and export the both the server/playground (like in the graphql-yoga example) but that didn't work when deploying to AWS like I expected it to. Is that the right approach and I'm just making a mistake somewhere along the way?

sid88in commented 6 years ago

Hey @abelovic thanks for looking into it. If you can create a PR with your implementation I am sure Graphcool folks can help you debug.

-Sid

Kisepro commented 6 years ago

@abelovic Did you find something ? Could help me a lot :-)

abelovic commented 6 years ago

@Kisepro - yes I have it working :) You will need to use webpack and you can use this as a starting point: https://github.com/jgeschwendt/serverless-prisma

Here is what I use:

Note: I am still using Prisma 1.7.4 & Prisma-binding 1.5.19 due to windows issues: https://github.com/prismagraphql/prisma/issues/2494

serverless.yml


custom:
  stage: ${opt:stage, self:provider.stage}
  webpack:
    webpackConfig: ./webpack.config.js
    includeModules:
      forceExclude:
        - aws-sdk
    packager: yarn
  serverless-offline:
    port: 4000

package:
  individually: true

plugins:
  - serverless-offline
  - serverless-webpack

provider:
  name: aws
  region: us-east-1
  runtime: nodejs8.10
  environment:
    PRISMA_DEBUG: ${env:PRISMA_DEBUG}
    PRISMA_ENDPOINT: ${env:PRISMA_ENDPOINT}
    PRISMA_SECRET: ${env:PRISMA_SECRET}
    PRISMA_SERVICE: ${env:PRISMA_SERVICE}

functions:
  graphql:
    name: gql-server-${self:custom.stage}
    handler: src/graphql.handler
    events:
      - http:
          cors: true
          integration: lambda-proxy
          method: get
          path: /
      - http:
          cors: true
          integration: lambda-proxy
          method: post
          path: /
  playground:
    name: gql-server-playground-${self:custom.stage}
    handler: src/playground.handler
    events:
      - http:
          cors: true
          integration: lambda-proxy
          method: get
          path: /playground

.graphqlconfig.yml

projects:
  app:
    schemaPath: src/schema.graphql
    extensions:
      endpoints:
        default: http://localhost:4000
  database:
    schemaPath: src/generated/prisma.graphql
    extensions:
      prisma: database/prisma.yml
      prepare-binding:
        output: src/generated/prisma.js
        generator: prisma-js

webpack.config.js

const path = require('path');
const slsw = require('serverless-webpack');
const webpack = require('webpack')
const nodeExternals = require('webpack-node-externals');

module.exports = {
  entry: slsw.lib.entries,
  target: 'node',
  mode: slsw.lib.webpack.isLocal ? 'development': 'production',
  optimization: {
    minimize: false
  },
  performance: {
    hints: false
  },
  devtool: 'nosources-source-map',
  externals: [nodeExternals()],
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader'
          }
        ],
      },
      {
        test: /\.graphql$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'graphql-import-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    new webpack.NamedModulesPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ],
  resolve: {
    extensions: [
      '.graphql',
      '.js'
    ]
  },
  output: {
    libraryTarget: 'commonjs',
    path: path.join(__dirname, 'dist'),
    filename: '[name].js',
    sourceMapFilename: '[file].map'
  }
};

graphql.js

const { GraphQLServerLambda } = require('graphql-yoga')
const { Prisma } = require('./generated/prisma.js')
const resolvers = require('./resolvers')
const typeDefs = require('./schema.graphql')

const handler = (event, ctx, callback) => {
  (new GraphQLServerLambda({
    typeDefs,
    resolvers,
    context: ctx => ({
      ...ctx,
      db: new Prisma({
        debug: process.env.PRISMA_DEBUG === 'true',
        endpoint: process.env.PRISMA_ENDPOINT,
        secret: process.env.PRISMA_SECRET
      })
    })
  })).graphqlHandler(event, ctx, callback)
};

module.exports = { handler };
fgiarritiello commented 6 years ago

Hi @abelovic, how are you handling websocket connections using the above project configuration?