GraphQL Server on Cloud Functions for Firebase
The smoothest GraphQL on FaaS DX to date!

What is GraphQL?
GraphQL is a data query language created by Facebook. Queries to the server specify the data they want to fetch while the GraphQL server exposes what is available and knows how to get it. The fundamental difference from REST is that we no longer expose predefined data. Therefore solving the problem of adding endpoints whenever we add new clients and versioning our REST endpoints.
Lee Byron’s blog post describes its use within Facebook and the advantages it offers. Another great resource is this Apollo post.
Why GraphQL with Firebase?
Firebase, although known predominantly for its real-time database, is a collection of services packaged, billed and deployed together. In my opinion, it offers the slickest developer experience of any cloud services available. My favorite features are:
- Single command deployment which can easily be customized to deploy any combination of your services and can easily integrate into a CI/CD pipeline.
- Runs on Google Cloud Platform and can easily integrate with the other services available here.
- No need to configure service-to-service IAM policies! This reduces the barrier to entry in a way the other cloud services cannot.
- A generous free-tier with PAYG billing.
I could go on.
So the developer experience (DX)is why, not because of anything to do with GraphQL. GraphQL can be hosted anywhere that responds to HTTP requests, so why not on Cloud Functions? Then we can utilize the DX of Firebase AND GraphQL!
Drawbacks of Ephemeral Compute Instances
While they do exist, I would argue that the reasons for not running GraphQL on serverless/FaaS are weak. The main argument for not using FaaS is the Cold Starts problem. The Serverless Framework community has covered this topic well (their blog is great! I recommend following them):
What is cold start in Serverless (FaaS)?
Cold start happens when you execute an inactive (cold) function for the first time. It occurs while your cloud provider provisions your selected runtime container and then runs your function. This process, referred to as cold start, will increase your execution time considerably.
While you’re actually running your function it will stay active (hot), meaning your container stays alive — ready and waiting for execution. But eventually after a period of inactivity, your cloud provider will drop the container and your function will become cold again.
So each request to our GraphQL endpoint would either, use a hot container, or a cold one. Since GraphQL Servers are a single API to your entire data graph, every request to fetch or mutate your data will go through here. Thus, you should have enough traffic to have some hot containers around making the Cold Start time irrelevant. If this does become an issue, you can simply run another Cloud Function to ping the desired Cloud Function and keep it warm.
GraphQL on Cloud Functions for Firebase
There are multiple packages available to leverage GraphQL in a Node.js environment. Facebook (well, the GraphQL team at Facebook) has express-graphql
which is a middleware implementation of GraphQL for the ExpressJS server package. As of writing, this is the most popular middleware with ~97,000 downloads in April, 2017 according to npmjs. The other prominent implementation is the Apollo developed graphql-server-express
, also a middleware for Express. It has far fewer downloads at ~35,000 downloads in the same period.
The number of downloads is a bad reason to choose between two packages, so let’s dig deeper. Facebook’s implementation seems to be a standard middleware for Express. While Apollo distinctly addresses the difference between the two packages:
The following features distinguish GraphQL Server from express-graphql, Facebook’s reference HTTP server implementation:
- GraphQL Server has a simpler interface and allows fewer ways of sending queries, which makes it a bit easier to reason about what’s going on.
- GraphQL Server serves GraphiQL on a separate route, giving you more flexibility to decide when and how to serve it.
- GraphQL Server supports query batching which can help reduce load on your server.
- GraphQL Server has built-in support for persisted queries, which can make your app faster and your server more secure.
Click here for a deeper dive into the Apollo docs.
Cloud Functions and an Express Server
At this point you may be asking “Why’re we going to run an Express Server on Cloud Functions. Don’t they already expose an HTTPS endpoint?”.
Well, yes, they do already expose an endpoint. However we cannot customize it with the GraphQL middleware like we can Express. Fortunately, Cloud Functions can be used with the Express.js web server framework. For more information about how this works, please read my previous post about Express on Cloud Functions.
So which package should we use?
In this tutorial we’ll be using Apollo’s graphql-server-express
package as I lean towards the community built around it. While express-graphql
is open-source and well maintained, I find that that GraphQL community around the Apollo tools will enable better integration, support and ultimately more customization.
Add GraphQL Server
In the ./firebaseFunctions
directory run:
yarn add express apollo-server-express \
graphql graphql-tools \
body-parser
Our ./firebaseFunctions/package.json
should now look like:
Now we have all the requried packages we will implement the Server in ./firebaseFunctions/graphql/server.js
:
And then use that server in ./firebaseFunctions/index.js
:
Add GraphQL Schema & Resolvers
Before we try and test this server, we will need to implement the GraphQL schema and the resolver methods to fetch the data. Instead of reinventing the wheel, we will use the same example data as the Apollo crew which is the basis for the dev.apollodata.com examples.
Create ./firebaseFunctions/graphql/data/schema.js
:
And ./firebaseFunctions/graphql/data/resolvers.js
:
Deploy & Test
We can deploy our server by running the now familiar yarn deploy
.
Testing the URL <function-name>/api
will yield a “Cannot GET null” 404 error, while adding the trailing “/” yields a “Cannot GET /” 404 error. Why does the trailing slash not solve our problem? Well, the Cloud Function is hosted on /api/
but our GraphQL server is hosted at /api/graphql
as we defined in our Express server in ./firebaseFunctions/index.js
. We must use our defined routes like so:
<function-name>/api/graphql
: accepts a GraphQL POST query string.
<function-name>/api/graphiql
: runs the GraphiQL browser IDE.
<function-name>/api/schema
: returns our schema in pretty-JSON.
And yes, no trailing “/” this time, graphql-server-express
knows what’s up!
GraphiQL
To enable independent development of the GraphQL server and schema from the client apps, Facebook developed the GraphiQL in-browser IDE. It let’s you explore the schema by browsing the schema and constructing and executing queries!


Notice the “Documentation Explorer” on the right side of the IDE. Use this to browser the queries, mutations and their parameters and structures.
Each query that is run through GraphiQL simply constructs the appropriate request object and sends a request through to our /api/graphql
endpoint. Thus, each time we run a query here it executes an instance (it may be new or use an existing one) of our Cloud Function. Pretty neat! Read more about it here.
A repository of the completed project is available here:
Conclusion
There you have it, GraphQL on Cloud Functions. This is only the beginning of my exploration into GraphQL on Firebase, so stay tuned by Following! Next up, GraphQL subscriptions while using GraphQL on Cloud Functions!
If you found this useful, please recommend and share with your friends & colleagues.