Apollo Server in Google Cloud Functions using NestJS

Martijn van de Brug
MisterGreen Engineering
3 min readMar 7, 2019

--

In this blog we will setup an Apollo GraphQL microservice in the Google Cloud Function environment, using NestJS for structuring our codebase.

This service will expose data about the Tesla cars in our system using a GraphQL interface.

42" cold gas thrusters on your Model 3? Elon would approve, as would Xzibit

Why?

Everyone loves microservices, but setting up an Appengine service for each service can become expensive. At MisterGreen we decided to run the smaller services in Google Cloud Functions, but would still like to be able to use GraphQL like our other services.

We use Apollo, because it is the most used GraphQL framework, used by companies like Airbnb and Medium (you’re using it right now!). Why GraphQL?

NestJS is an Angular like framework which will add some structure to our codebase. It separates our code into Modules and Providers, and has its own Dependency Injection mechanism.

Setup

I’m going to skip discussing most of the boilerplate needed, but the complete code used in this blog can be found here. It comes down to this:

  • Typescript, because…. just use Typescript . There is a command in the package.json to compile Typescript to JS using concurrently, but you can choose to use ts-node if you prefer.
  • package.json, setup with the dependencies you need. The most important ones are from NestJS and apollo-server-cloud-functions.
  • dev-server.ts, this file lets you run the Cloud function locally for testing purposes.

Let’s do some coding

Let’s see what this means in terms of code.

AppModule

NestJS starts with an AppModule.ts, which will hold all other modules. Lets create it:

This module loads all .graphql files and sets them as typeDefs. The TypeDefs define the GraphQL schema. We also need resolvers, which will connect our logic to the GraphQL schema. These resolvers are imported from TeslaModule, which we will create later.

Main

Next, we will create the main.ts which is the starting point of our application:

The function bootstrap() initializes our Cloud function handler. 2 important thing are happening here:

  • NestFactory.createApplicationContext(AppModule) — This creates a NestJS execution context instead of a server. Because we are going to deploy this to Cloud Functions, we don’t need a full server.
  • new ApolloServer() and server.createHandler() — These both originate from the apollo-server-cloud-functions package. This package also creates an Apollo handler instead of a server.

TeslaModule

This is the module that will contain the GraphQL type definitions and resolvers. Create the following file in src/app/tesla :

This is just a simplified example for this blog ofcourse. Normally we would create a tesla.service.ts and have NestJS instantiate and inject it.

After Query and Mutation, we have a tesla.wheels link, which ensures we are only retrieving wheels when the user is requesting this property.

GraphQL type definitions

We need GraphQL type definitions to expose to the outside world. We are going to do this by creating a file in src/app/tesla/type-defs.graphql:

Typescript types

In TeslaModule we can see Tesla and Wheel interfaces being imported from generated/graphql-types.ts. These types are generated using the graphql-code-generator package.

Just run yarn generate-types to re-generate the types. Make sure you’re app is running locally first! The configuration for the generator can be found in codegen.yml.

Run it!

You should now be able to run the application locally:

yarn serve

The GraphQL playground can now be used at localhost:8080 using your browser.

We can now use our GraphQL playground!

Recap

The most important things to run an Apollo GraphQL server with NestJS on Google Cloud function are:

  • Create a NestJS context instead of a server.
  • Create an Apollo handler instead of a server.

Don’t forget to check out the complete code on GitHub to be able to run the dev-server and deploy to Cloud functions.

Enjoy! Let me know if you have any questions.

--

--