Scalable APIs with GraphQL and Netlify Functions
Tags: serverless, javascript, webdev, tutorial
Published: 2021-01-22 15:36:49

---
title: Scalable APIs with GraphQL and Netlify Functions
published: true
description: 
tags: serverless, javascript, webdev, tutorial
cover_image: https://dev-to-uploads.s3.amazonaws.com/i/h5o8e1k25p165si5v2od.png
canonical_url: https://www.takeshape.io/articles/scalable-apis-with-graphql-and-netlify-functions/
---

In this tutorial, we will be exploring serverless functions by learning how to use them with GraphQL to build scalable APIs.

## What is serverless?

A serverless function is a way for adding a backend to your app without managing a server, virtual machine, or docker container. Behind every serverless function invocation is a server hosted and managed by a cloud provider such as AWS, Google Cloud, Netlify, Vercel, and so on. The providers are abstracting away a lot of the complexity so you can focus on just what your function needs to do. Serverless functions are basically functions-as-a-service.

## **What we’re building**

In this tutorial, we will be using Netlify Functions, which are built on top of AWS Lambda Functions. We’ll be building a Project Tracker with GraphQL, serverless functions, and Airtable. We will be using The Airtable API to create and retrieve projects. Let’s get started!

## Setting up

Before we get into creating a new lambda function, we need to sign up for an [Airtable](https://airtable.com/account) account to be able to use it as a DB. After you create an account, open your command-line interface and running the following:

```
npm install netlify-cli -g
```

This command will install [Netlify](https://docs.netlify.com/cli/get-started/#installation) CLI, which we will us to create a new serverless function. Next we need to set up our project, execute the following:

```
mkdir functions && touch netlify.toml
```

The command will first create a new folder named `functions` then will create a new file `netlify.toml` at the root. Netlify uses this file to configure the resources you’ll be using, in this case functions. With this in place, add the following code below to `netlify.toml`.

```
// netlify.toml

[build]
    functions = "functions"
```

These two lines tell Netlify that our serverless functions live in a folder named `functions`. Now, open your CLI and make sure to be in the folder that contains the `functions` folder.

```
netlify functions:create serverless-graphql
```

The Netlify CLI will prompt you with options to choose between several ready to use templates. Choose the one named `>[apollo-graphql] GraphQL function using Apollo-Server-Lambda!`. It’s the starter for the serverless function that uses Apollo GraphQL. Once the project is initialized, `cd` into the `functions` folder, then install the [Airtable SDK](https://airtable.com/app3Cx2QgrU126Pj0/api/docs#javascript/introduction).

```
npm install airtable
```

Next, create a `.env` file at the root of the project and replace the variables with your credentials.

```
// .env

AIRTABLE_API_KEY=<your-api-key>
AIRTABLE_BASE_ID=<your-table-base-id>
AIRTABLE_TABLE_NAME=<your-table-name>
```

1. `AIRTABLE_API_KEY` is your API key on your Airtable account.
2. `AIRTABLE_BASE_ID` is the id of your DB table ([see here](https://airtable.com/app3Cx2QgrU126Pj0/api/docs#javascript/introduction)).
3. `AIRTABLE_TABLE_NAME` is the name given to your table.

With our setup and configuration complete, we can dive into coding our serverless function.

## Building the serverless function with GraphQL

First, structure the project like so:

```
functions
├── graphql.js
├── utils
|  └── airtable.js
└── package.json
```

As you can see, the logic to interact with Airtable is holden by the file `airtable.js`. The entry point of the serverless function is `graphql.js`.

**Connecting with Airtable**

Let’s add the code below to the file `airtable.js`.

```
// utils/airtable.js

const Airtable = require('airtable')

const { AIRTABLE_API_KEY, AIRTABLE_BASE_ID, AIRTABLE_TABLE_NAME } = process.env

const base = new Airtable({ apiKey: AIRTABLE_API_KEY }).base(AIRTABLE_BASE_ID)

const table = base(AIRTABLE_TABLE_NAME)

const getAllProjects = async () => {
  const allProjects = await table.select({}).firstPage()
  return allProjects.map(({ id, fields }) => transformResponse(id, fields))
}

const addProject = async ({ project }) => {
  const { name, description, date } = project
  const createProject = await table.create([
    {
      fields: {
        name,
        description,
        date,
        status: 'In progress',
      },
    },
  ])
  const { id, fields } = createProject[0]
  return transformResponse(id, fields)
}

const transformResponse = (id, fields) => ({
  id,
  name: fields.name,
  description: fields.description,
  date: fields.date,
  status: fields.status,
})

exports.getAllProjects = getAllProjects
exports.addProject = addProject
```

`Airtable` allows us to connect our app to Airtable with the credentials passed in as arguments to it. After that, we initialize the DB table with the `table` constant.

Next, we retrieve all `projects` from `Airtable` using the function `getAllProjects()`. To add a new project, we rely on the method `addProject()`, which receives the object to add as a parameter. Finally, we use the method `table.create()` to persist the data on the DB.

Now, we have the functions needed to add and fetch the projects from Airtable. Let’s use them in the file `graphql.js` to perform the queries.

## Creating the API with GraphQL

```
// graphql.js

const { ApolloServer, gql } = require('apollo-server-lambda')
const { getAllProjects, addProject } = require('./utils/airtable')

const typeDefs = gql`
  type Project {
    id: ID
    name: String
    description: String
    date: String
    status: String
  }
  input ProjectInput {
    name: String
    description: String
    date: String
  }
  type Query {
    getProjects: [Project]
    addProject(project: ProjectInput): Project
  }
`

const resolvers = {
  Query: {
    getProjects: () => {
      try {
        const allRecords = getAllProjects()
        return allRecords
      } catch (error) {
        throw new Error(error)
      }
    },
    addProject: (_, args) => {
      try {
        const createProject = addProject(args)
        return createProject
      } catch (error) {}
    },
  },
}

const server = new ApolloServer({
  typeDefs,
  resolvers,
})

const handler = server.createHandler()

module.exports = { handler }
```

If you have experience with Apollo Server, you should already notice that the library used here (`apollo-server-lambda`) is different from the one used for building servers. This package uses middleware to inject our lambda serverless function to Apollo Server.

Next , we import the functions `getAllProjects` and `addProject` from `airtable.js`. With this, we can define a new GraphQL Schema using `gql`. The query `getProjects` has to return an array of type `Project`. The method `addProject` expects an object of type `ProjectInput` as a parameter and should return a value that reflects the `Project` type.

Any GraphQL Schema has to have a GraphQl resolver that corresponds to it. That’s why, here, we have on the `resolvers` object, the functions `getProjects()` and `addProject()`. The first fetch all projects from Airtable and the second add a new object to the table.

Now, we have a schema and a resolver. We need to pass in the values to the constant `server` to let it handle the request when the endpoint `/graphql` is hit.

## Testing the GraphQL API

With this step, the serverless app is ready to be tested in the browser. So, begin by browsing to the root of the project and running this command:

```
netlify dev
```

Our serverless function should be up and running and accessible here:

The app will land on the GraphQL Playground. It’s a neat tool built on top of GraphiQL. It’s a GraphQL IDE for sending queries or mutations, exploring the API docs, sending HTTP headers, and more.

`http://localhost:8888/.netlify/functions/graphql`

Now, add this code block below to create a new project.

```
mutation {
  addProject(project: { name: "My first project", description: "First project's description", date: "2020-12-11" }) {
    name
    description
    date
    status
  }
}
```

After sending the query, you should see this:

![addProject query](https://dev-to-uploads.s3.amazonaws.com/i/8ld7u7jhjj2467g5y3vq.png)

create-post

```
{
  getProjects {
    id
    name
    description
    date
    status
  }
}
```

Once all projects are fetched, the result should look like this:

![getProjects query](https://dev-to-uploads.s3.amazonaws.com/i/8kh8yuinxsa0hxv01ut9.png)

get-all-posts

## Next steps

Awesome! Our serverless function is looking nice. We’ve built a GraphQL API using serverless functions and Airtable. Let’s now deploy it to Netlify!

To do so, we first need to [sign up here](https://www.netlify.com/). Then, initialize our app with git. Make sure to be at the root of the project before executing the following.

```
git init
```

Add a `.gitignore` file at the root of the project.

```
touch .gitignore
```

Add this code block to ignore the files listed below when adding changes to git.

```
// .gitignore

/functions/node_modules
/functions/.env
```

Add and commit changes to git.

```
git add -A && git commit -m 'Ready to deploy on Netlify'
```

Create a new repository on [Github](https://github.com/) and follow the steps to push your project. Next, go to Netlify and connect your Github repo. Move the `package.json` file to the root of the project, then create the environment variables on Netlify.

![Environment Variables](https://dev-to-uploads.s3.amazonaws.com/i/a74l9wgo8e2g7lhpzbgc.png)

Deploy your serverless functions. We can now preview and interact with our app here: `https://graphql-airtable.netlify.app/.netlify/functions/graphql`

![getProjects Query](https://dev-to-uploads.s3.amazonaws.com/i/obusvu396hn2rrdg7mnb.png)

You can find the finished project in this [Github repo](https://github.com/ibrahima92/serverless-graphql-airtable). Thanks for reading!

## Conclusion

Serverless is an exciting piece of technology. It allows us to build up a backend quickly without the hassle of managing a server, which brings us to the JAMStack. An architecture designed to make the web faster, more secure, and easier to scale with static sites and serverless functions.