Create a Serverless GraphQL server

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

Yat Badal
March 1, 2023
Blog cover image

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

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

If you’ve 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 an 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.jsconst 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.ymlservice: serverless-graphqlplugins:
 - serverless-webpack
 - serverless-offlinecustom:
 webpack:
   webpackConfig: ./webpack.config.js
   includeModules: trueprovider:
 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.jsimport 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.ymlfunctions:
 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

*Original article published on Hackernoon

As seen on FOX, Digital journal, NCN, Market Watch, Bezinga and more