Apollo Server in Google Cloud Functions using NestJS
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.
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 usingconcurrently
, but you can choose to usets-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()
andserver.createHandler()
— These both originate from theapollo-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.
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.