Yatin badal

@YatinBadal

Create a Serverless GraphQL server using Express, Apollo Server and AWS Lambda

…because who wouldn’t want a Serverless GraphQL server, right !?

If you have mucked around with GraphQL, Serverless and love JavaScript — you’ve come to the right place. What’s better than mixing a few of the most exciting technologies in recent times, not much, eh.

Continuing in our Serverless journey, and further building on a previous post, where we’ve explored Rendering and serving a Create-React-App from an Express server running within a Lambda function — let’s now turn our focus towards GraphQL and marry it with Serverless. And, in doing so, eliminate the need to have a continuously running GraphQL instance, an ops dream.

We will be using AWS Lambda functions along with the Serverless Framework for our server. Our Lambdas will run the Node.JS 8.1 runtime. We will also make use of Webpack for all it’s bundling goodness and Babel to transpile our pile.

In order to get our Serverless GraphQL server up and running we will need to:

  • Setup a Serverless
  • Create and Express App
  • Pull in and configure Apollo Server

Right, let’s get started!

Serverless + Webpack

First thing’s first, install the Serverless framework and all the necessary dependencies it’ll need:

$ npm i -S serverless serverless-webpack serverless-http serverless-offline 

We will also need to install Webpack, node-externals packages, and babel-loader. Next create a config file for Webpack:

$ npm i -D webpack webpack-node-externals babel-loader
$ touch webpack.config.js

and place the following, basic config in it:

// webpack.config.js
const path = require("path");
const slsw = require("serverless-webpack");
const nodeExternals = require("webpack-node-externals");
module.exports = {
entry: slsw.lib.entries,
target: "node",
mode: slsw.lib.webpack.isLocal ? "development" : "production",
optimization: {
minimize: false
},
performance: {
hints: false
},
devtool: "nosources-source-map",
externals: [nodeExternals()],
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader"
}
]
}
]
},
output: {
libraryTarget: "commonjs2",
path: path.join(__dirname, ".webpack"),
filename: "[name].js",
sourceMapFilename: "[file].map"
}
};

You can find more information about the serverless-webpack plugin here.

Next we’re going to need to create and configure our serverless.yml file:

$ touch serverless.yml

Place the following YML in it:

// serverless.yml
service: serverless-graphql
plugins:
- serverless-webpack
- serverless-offline
custom:
webpack:
webpackConfig: ./webpack.config.js
includeModules: true
provider:
name: aws
runtime: nodejs8.10
stage: dev
region: eu-west-1

We will add and configure our functions next.

Express + Apollo Server

Right, let’s move on to our server. We will need to install Express, Apollo Server and a few other dependencies:

$ npm i -S express apollo-server-express graphql

We’re also going to use the Prisma GraphQL playground to test our fancy server. Let’s install the necessary packages:

$ npm i -D graphql-playground-middleware-express

Create an index.js file which will contain our server code as well as be our entry point:

$ touch index.js

Place the following code in it:

// index.js
import express from "express";
import serverless from "serverless-http";
import graphiql from "graphql-playground-middleware-express";
import { ApolloServer, gql } from "apollo-server-express";
const typeDefs = gql`
type Query {
hello: String
}
`;
const resolvers = {
Query: {
hello: () => "world"
}
};
const app = express();
const server = new ApolloServer({
typeDefs,
resolvers,
path: "/graphql"
});
server.applyMiddleware({ app });
app.get("/playground", graphiql({ endpoint: "/graphql" }));
const handler = serverless(app);
export { handler };

Right, our index.js has been setup to accommodate two lambda functions, one for the GraphQL Apollo Server and the other for the Playground. Update the serverless.yml file and add the two functions we need:

// serverless.yml
functions:
graphql:
handler: index.handler
events:
- http:
path: graphql
method: post
cors: true
playground:
handler: index.handler
events:
- http:
path: playground
method: get

…and with that, we’ve pretty much concluded the setup. Let’s give our GraphQL Apollo Server a test! Recall, earlier, we added serverless-offline as a dependency, let’s go ahead and startup our server offline:

$ npx sls offline start

This will start a local instance of our server. You should see the following output:

Running our GraphQL server for the first time!

You’ll notice that our two endpoints will be created, /graphql being our GraphQL server endpoint and our playground at /playground .To test our server, let’s navigate to our playground, http://localhost:3000/playground

Execute a simple query, and behold the magic of a Serverless GraphQL server…😎

Our Serverless GraphQL server in all it’s glory 😎

— Finally

In a few simple steps, we’ve created a simple Express and GraphQL server on AWS Lambda. To deploy our server, all we need to do now, is run:

$ npx sls deploy -v

Hook up your server to your React frontend, server-side rendered from a Lambda too and you’ve got yourself quite a flexible Serverless solution. This concludes our little attempt at marrying Serverless and GraphQL — two of the hottest technologies in the scene right now.

You can find the code for this post at: https://github.com/FBI23/serverless-express-graphql

Topics of interest

More Related Stories