TypeGraphQl: Usage with Netlify Functions/AWS Lambda

711 views Asked by At

I was finally able to get TypeQL working with Netlify Functions / AWS Lambda after a day of work, going over the docs and examples, and in the end desperate brute force.

I'm sharing my working code here for others (or for future reference of my own :P ) as it contains some counterintuitive keyword usage.

Normal Approach

The error I kept getting when using the simple example was:

Your function response must have a numerical statusCode. You gave: $ undefined

I searched of course in the issues, but none of the suggested solutions worked for me.

2

There are 2 answers

3
Aerodynamic On

Working Code

import 'reflect-metadata'
import { buildSchema } from 'type-graphql'
import { ApolloServer } from 'apollo-server-lambda'
import { RecipeResolver } from 'recipe-resolver'

async function lambdaFunction() {
  const schema = await buildSchema({
    resolvers: [RecipeResolver],
  })

  const server = new ApolloServer({
    schema,
    playground: true,
  })

  // !!! NOTE: return (await ) server.createHandler() won't work !
  exports.handler = server.createHandler()
}

// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// !!! NOTE: weird but only way to make it work with
// AWS lambda and netlify functions (netlify dev)
// also needs a reload of the page (first load of playground won't work)
lambdaFunction()
// exports.handler = lambdaFunction wont work
// export { lambdaFunction as handler } wont work
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

Also I got some reflection errors from the simple example

Unable to infer GraphQL type from TypeScript reflection system. You need to provide explicit type for argument named 'title' of 'recipe' of 'RecipeResolver

So I had to figure out how to add explicit type to @Arg:

// previous:
// recipe(@Arg('title') title: string)
// fixed:
   recipe( @Arg('title', (type) => String) title: string
0
Linh P On

I share the code that works for me

// File: graphql.ts

import 'reflect-metadata'
import { buildSchema } from 'type-graphql'
import { ApolloServer } from 'apollo-server-lambda'
import { ApolloServerPluginLandingPageGraphQLPlayground } from 'apollo-server-core'
import { RecipeResolver } from './recipe-resolver'

export const createHandler = async function(){
  const schema = await buildSchema({
    resolvers: [RecipeResolver],
  })

  const server = new ApolloServer({
    schema,
    introspection: true,
    plugins: [ApolloServerPluginLandingPageGraphQLPlayground()],
  })

  return server.createHandler()
}

export const handler = async function(event, context, callback) {
  const graphqlHandler = await createHandler()
  return await graphqlHandler(event, context, callback)
}

// Lambda: graphql.handler
  • node16.x
  • type-graphql ^1.1.1
  • graphql ^15.3.0
  • apollo-server-lambda: ^3.10.2