Blog post
Serverless & GraphQL
Serverless & GraphQL
Nikola Ivanović
2021-04-06
Before reading this article, I recommend reading the one about the Serverless platform and simple deployment of the Next.js app with Serverless.
Our main goal is to deploy GraphQL backend with Fastify framework to AWS Lambda using Serverless framework.
Fastify is a web framework highly focused on providing the best developer experience with minor overhead and a robust plugin architecture. It is inspired by Hapi and Express and is one of the fastest web frameworks.
Core features are:
Highly performant
Extendible
Schema-based
Logging
Developer friendly
Getting started with Fastify is easy. Just create an empty folder, and inside it generate a fastify project:
1npm init fastify
and after that, install dependencies:
1npm install
You can then start the app in dev mode using npm run dev
, but that is not where we want to stop now.
Also, if you have an existing project, you can install Fastify as a dependency:
1npm i fastify --save
The next step is installing fastify-gql, which gives us the best of two dependencies: Fast and efficient server and easy and optimal query support from GraphQL:
1npm i fastify fastify-gql
*this command covers both the first step and the fastify-gql step
We will use the following example and write down in our app.js
the following code:
1'use strict'
2
3const Fastify = require('fastify')
4const GQL = require('fastify-gql')
5
6const app = Fastify()
7
8const schema = `
9 type Query {
10 add(x: Int, y: Int): Int
11 }
12`
13
14const resolvers = {
15 Query: {
16 add: async (_, { x, y }) => x + y
17 }
18}
19
20app.register(GQL, {
21 schema,
22 resolvers
23})
24
25app.get('/', async function (req, reply) {
26 const query = '{ add(x: 2, y: 2) }'
27 return reply.graphql(query)
28})
29
30app.listen(3000)
Our code can now run on localhost:3000 by running it from the terminal using:
1node app.js
Using AWS services with Fasitfy is also a great combo and boost to your server response.
Add this feature using:
1npm install aws-lambda-fastify
Now we need to create a new lambda.js
file in our root folder, which looks like this:
1const awsLambdaFastify = require('aws-lambda-fastify')
2const app = require('./app')
3
4const proxy = awsLambdaFastify(app)
5// or
6// const proxy = awsLambdaFastify(app, { binaryMimeTypes: ['application/octet-stream'] })
7
8exports.handler = proxy
9// or
10// exports.handler = (event, context, callback) => proxy(event, context, callback)
11// or
12// exports.handler = (event, context) => proxy(event, context)
13// or
14// exports.handler = async (event, context) => proxy(event, context)
And add a little tweak to your app.js
file by removing the last line of code and replace it with this:
1if (require.main === module) {
2 // called directly i.e. "node app"
3 app.listen(3000, (err) => {
4 if (err) console.error(err)
5 console.log('server listening on 3000')
6 })
7} else {
8 // required as a module => executed on aws lambda
9 module.exports = app
10}
When executed in your lambda function, we don't need to listen to a specific port, so we export the app.js
in this case. The lambda.js
file will use this export.
You can now rerun the app using the same command node app.js
.
Now that we covered the basics about using Fasitfy combined with GraphQL and AWS, we can get back to our Serverless deployment, which includes configuring our serverless.yml, which was mentioned in the previous article:
1#serverless.yml
2
3functions:
4 graphql:
5 handler: handler.graphqlHandler
6 events:
7 - http:
8 path: graphql
9 method: post
10 cors: true
Any HTTP POST event on the path /graphql
will trigger the graphql Lambda function and will be handled by graphqlHandler
.
The rest of the configuration is just creating a GraphQL schema, Lambda function with your needs, and you are ready to go!
In sum, powering your GraphQL endpoint with a Serverless backend solves scaling and availability concerns outright, and it gives you a big leg up on security. It’s not even that much code or configuration!
Nikola Ivanović
2021-04-06
Nikola is JavaScript developer passionate about React, CSS, Animations and UX design. Loves frontend work but he is not afraid to touch backend.
Leave your thought here
Your email address will not be published. Required fields are marked *