This quick demo assumes you’re already familiar with Netlify as a deployment service, GraphQL as an API technology and React.
The starting point was a normal React project created with create-react-app
then deployed on Netlify (you know…the usual)
Then I arrived to the point where I found out I needed an API to do some backend-related stuff, I (innocently) reached out to create a new repository, wrote some GraphQL resolvers/mutations, committed the whole thing but just when I was looking for a cheap vps to host it in, I stopped for a second then said to my self: why not do it on Netlify itself?
Narrator: he did not regret it.
The process was as straightforward as this:
-
I’ve started by completely moving the backend files from their separate repo to inside
src/
folder in the frontend repo: Then I’ve added netlify-lambda as a dev dependency to the project; this is a tool created by the netlify team and provides a runtime for lambda functions.
-
I did not have a
netlify.toml
file at the time so I created one, and updated the content with this:
[build] command = "yarn build" # the command you run to build this file functions = "built-lambda" # netlify-lambda builds to this folder AND Netlify reads functions from here publish = "build" # create-react-app builds to this folder, Netlify should serve all these files statically // This helps the `netfliy-lambda` do its job and helps Netlify figuring out where to look for your functions when deployed. // Note: the `functions` field will probably be different in your project depending on where you decided to put the GraphQL functions
The I’ve added two new scripts to my
package.json
:
-”start:lambda”:”netlify-lambda serve src/lambda”
-”build:lambda”:”netlify-lambda build src/lambda”
-
before going all lambda crazy, the backend repository was using a normal apollo-server but now I needed to find a lambda compatible one, luckily apollo-server-lambda does exactly this and barely required any changes on the existing files, the
graphql.js
looked like this:
const { ApolloServer } = require('apollo-server-lambda'); const { typeDefs } = require('./lib/typeDefs'); const { resolvers } =require('./lib/resolvers'); const lambda = newApolloServer({ typeDefs, resolvers, playground: true, introspection: true ); exports.handler = lambda.createHandler({ cors: { origin: '*', credentials: true } });
The last piece now was to wire the GraphQl client with the Netlify function:
On the frontend, I’m working withurql
so I had to update the client initialisation to this:
const client = createClient({
url: process.env.NODE_ENV === 'development'
? 'http://localhost:9000/.netlify/functions/graphql'
: '/.netlify/functions/graphql'
})
The http://localhost:9000/.netlify/functions/graphql
URL is the default one when running npm run start:lambda
locally but when deploying to Netlify the functions are hosted on the same domain hence the check.
Note: This code is still valid for your favorite GraphQL client too.
Now once I published these new changes to Netlify, it detected that I’ve added a new function and did its magic:
Couple of notes
- When working with databases, the standard approach of starting the database with the server does not work in this case since the lambda function is given a limited time to run on every request and will be shut down after the request is resolved, the solution is to open a database connection on every incoming request and cache it the between requests. I was able to do that (with
mongdb
in my case) using something like:
let cachedDb
if(cachedDb && cachedDb.serverConfig.isConnected()){
context.db = cachedDb;
} else {
context.db = await connectDB();
cachedDb = context.db;
}
- You can simulate a full working Netlify runtime locally using their Netlify Dev | Netlify tool, this comes handy when you want to debug you full wired app locally.
Relevant Links
- Docs for Netlify functions: https://www.netlify.com/docs/functions/
- Netlify lambda: https://github.com/netlify/netlify-lambda
- Apollo server lambda: apollo-server/packages/apollo-server-lambda at master · apollographql/apollo-server
- Netlify dev: Netlify Dev | Netlify
Top comments (1)
that sounds interesting. Is this project online? If so, where? I'd like to try it and compare the speed.