Using Google Cloud functions (or your favorite serverless computing provider) setting up a GraphQL Server has never been easier! I wanted to try my hand at setting up my first Cloud Function and found that James Hegedus ’s tutorials in setting up a GraphQL server using graphql-server-express were hugely helpful in both wrapping my head around the pros and cons of cloud computing and the basics of setting up a GraphQL server! https://codeburst.io/graphql-server-on-cloud-functions-for-firebase-ae97441399c0. I, however, wanted to set up my GraphQL server using Apollo Server so that I could reap the benefit of using the same platform in both my client and server. I struggled (and banged my head against my keyboard a few times) in actually getting my Apollo Server to be configured correctly and to integrate the Google Cloud Function’s http response methods. A lot of the old docs and tutorials I found were actually using the Apollo Server API from version 1.x. Here’s some quick snippets to help you out if you, like me, were stuck or confused with this process!
This tutorial assumes that you have the FireBase CLI installed globally on you computer and that you have properly logged in and configured that tool. This tutorial also assumes that you have a project created at FireBase that you can attach this function to.
mkdir graphql-test
cd graphql-test
firebase init functions
After running firebase init you will need to choose your project from the FireBase CLI. Next, choose if you’d like this project to support JavaScript or TypeScript (for simplicity I chose JavaScript). Next, the CLI prompts you to choose a pre-configured linting tool — ESLint, I selected yes(pro tip ALWAYS use a linter!). Finally, the CLI creates the basic directory structure of you cloud function and can install all dependencies via npm for you. Your directory should look like this at this point:
.
|-- .firebaserc - json scheme that describes project links
|-- firebase.json - json scheme with initial predeploy scripts
|-- functions
|-- node_modules
|-- .eslintrc.json
|-- index.js -- entry point of your cloud function
|-- package-lock.json
|-- package.json
I’d suggest cd’ing into functions as all the code you want to write for your cloud function needs to happen in that directory. Don’t make the simple mistake (like me) or installing dependencies in the root directory (which is really meant for firebase configuration) and creating two package.jsons.
Once you cd into functions run the following command to save required dependencies for the project.
npm install apollo-server-express cors express graphql --save
Next you’ll want to create a server.js file. Here’s what should be included in that file.
// require all dependencies to set up server
const express = require("express");
const { ApolloServer, gql } = require("apollo-server-express");
// cors allows our server to accept requests from different origins
const cors = require("cors");
function configureServer()
{
// invoke express to create our server
const app = express();
//use the cors middleware
app.use(cors());
// Simple graphql schema
const typeDefs = gql`
type Query {
"A simple type for getting started!
"hello: String}`;
// Very simple resolver that returns "world" for the hello query
const resolvers = {
Query: {
hello: () => "world"}};
const server = new ApolloServer({typeDefs,resolvers
}
);
// now we take our newly instantiated ApolloServer and apply the
// previously configured express application
server.applyMiddleware({ app });
// finally return the application
return app;}module.exports = configureServer;
That function will set up a very basic ApolloServer integrated with an express application.
The next step is to modify our index.js — the entry point into our function to use this function and set our GraphQL server to accept requests at a certain endpoint.
Here’s what your index.js should look like:
// require both the firebase function package to define function // behavior and your local server config function
const functions = require("firebase-functions");
const configureServer = require("./server");
//initialize the server
const server = configureServer();
// create and export the api
const api = functions.https.onRequest(server);
module.exports = { api };
That’s all you need to do to configure your api! Run the following command and your function will be deployed to the web!
firebase deploy
It’s important to note how both Google Cloud Functions and ApolloServer configure their urls. In the code above we are using the ES6 Property Value short hand. We could write that export more explicitly as
module.exports = {
api:api
}
That means that we are exporting an object where our variable api, which contains the firebase https request handler with our configured server is attached to the key of api. Firebase handles that key by appending it to the path to your server that it creates for you. Therefore our GraphQL server is accessible at https://us-central1-YOUR-PROJECT.cloudfunctions.net/api
However, the initial GraphQL initialization actually automatically configures an additional path for you (since we didn’t pass a path value in the applyMiddleware step). So in reality, the GraphQL endpoint that you can query will be available at https://us-central1-YOUR-PROJECT.cloudfunctions.net/api/graphql. If you navigate to that URL you should see the GraphQL Playground and be able to submit your hello query structured as follows:
{
hello
}
and get the string “world” response. I’ve had some wonky behavior with the playground UI “hosted” on your function (I’m using hosted in quotes as there is no persistent connection to the function due to the ephemeral nature of serverless computing but you can copy the CURL command from the playground which should look something like this:
curl 'https://us-central1-YOUR-PROJECT.cloudfunctions.net/api/graphql' -H 'Accept-Encoding: gzip, deflate, br' -H 'Content-Type: application/json' -H 'Accept: application/json' -H 'Connection: keep-alive' -H 'DNT: 1' -H 'Origin: https://us-central1-choozle-crews.cloudfunctions.net' --data-binary '{"query":"{hello}"}' --compressed
Run that in your terminal (and because we configured cors), you’ll get the following JSON back!
{"data":{"hello":"world"}}
That’s it folks! You’ve got a fully configured and ready to roll GraphQL API set up on a Google Cloud Function serverless environment using Apollo Server. Next you can move your GraphQL schema and resolvers into separate files, import your own data, connect to a datasource (FireStore is a great and easy option since you are already in the FireBase ecosystem) and create awesome apps using GraphQL.
Source: Medium
The Tech Platform
Comments