Adding serverless APIs to Gatsby projects in Vercel
Tags: javascript, gatsby, vercel
Published: 2020-10-31 20:03:20

---
title: Adding serverless APIs to Gatsby projects in Vercel
published: true
date: 2020-10-31 15:00:00 UTC
tags: javascript, gatsby, vercel
description: I show how it's possible to dynamically load data into a Gatsby page using Vercel Serverless Functions.
canonical_url: https://jvarness.blog/adding-serverless-apis-to-gatsby-projects-in-vercel/
---

Hey everyone! It’s been a solid two weeks since I’ve actually written a blog. I’ve been feeling really under the weather, so I’ve been mostly taking the last few weeks easy (don’t worry, it wasn’t/isn’t COVID). That, and Pokemon Crown Tundra got released, so I’ve been playing a lot of that lately, but it feels nice to be back to writing some blogs!

In the blog I wrote about [how I created my blog](https://jvarness.blog/how-this-site-was-made), I briefly mentioned that one of the reasons that I didn’t need to use Next.js for this site was because of the fact that it offered more functionality than I needed. All the pages on this site are built statically, and Next.js can do that too, but it also has great support for [dynamic routes and APIs](https://nextjs.org/docs/api-routes/introduction).

I’m not convinced that this point that I’ll ever need dynamic routing built into this site since it’s using Gatsby. However, I might want to create APIs later for mailing lists, forms, etc. If I ever do need those APIs, Vercel actually makes it really easy to add APIs to any project.

Originally this post was going to be about how easy making microservice APIs is using [micro](https://github.com/vercel/micro), but then I discovered that micro was designed to be ran within a container, and that Vercel has better support for adding APIs to any Node project using it’s [Serverless Helper Functions](https://vercel.com/docs/runtimes#official-runtimes/node-js/node-js-request-and-response-objects).

## Adding an API

Adding serverless APIs to Vercel projects is dead simple. You can review the link above and find some instructions. What I’ve done on this site is I’ve deployed the example shown in the link to a route on my website at [`api/examples/hello-world`](https://jvarness.blog/api/examples/hello-world). For posterity, the code just looks like this:

```js
module.exports = (req, resp) => {
  const { name = "World" } = req.query;
  resp.json(`Hello ${name}!`);
};
```

This is a fairly straight-forward function: it accepts two objects, one representing the `req`uest, which contains all the query parameters and any applicable bodies, and then an object we can use to send the `resp`onse with.

I added this route by simply creating an `api` folder at the root of my project. Vercel will build out serverless API routes using the file structure defined within the `api` folder, and will serve any `.js`, `.go`, `.py`, or `.rb` files defined within as serverless lambda functions.

## Consuming in Gatsby

I was really hoping to consume the API directly from this blog post, but I’m not using [mdx](https://github.com/mdx-js/mdx) for my posts quite yet, and injecting JavaScript in-line on a markdown file didn’t really seem like a very _safe_ thing to try and do, nor did I think it was feasible. SO, instead, I created an example page of how a Gatsby page might consume a serverless function.

You can view the demo [here](https://jvarness.blog/examples/api-example), but I’ll talk more about the code here. You might consider opening the demo page up on another tab.

In order to get the query parameters, Gatsby passes in [`location` data](https://www.gatsbyjs.com/docs/location-data-from-props/) to each of it’s pages. We can use this, along with the [`fetch`](https://www.gatsbyjs.com/docs/recipes/querying-data/#querying-data-client-side-with-fetch) API to grab the query params, can call our serverless function with the parameters:

```jsx
import React, { useEffect, useState } from 'react'
import { Link } from "gatsby"
import Layout from "../../components/layout"
import SEO from "../../components/seo"
import queryString from "query-string"

export default ({location}) => {
  const { search } = location
  const { name = "World" } = queryString.parse(search)
  const [greeting, setGreeting] = useState('Loading...')

  useEffect(() => {
    fetch(`/api/examples/hello-world?name=${name}`)
      .then(resp => resp.json())
      .then(greet => setGreeting(greet))
  }, [name])

  return (
    <Layout>
      <SEO title={`Hello ${name}`}/>
      <section className="hero is-white is-large">
        <div className="hero-body">
          <h1 className="title">{greeting}</h1>
        </div>
      </section>
      <section>
        If you stumbled upon this page not knowing what it was, go <Link to={`/adding-serverless-apis-to-gatsby-projects-in-vercel`}> here.</Link>
      </section>
    </Layout>
  )
}
```

We’re able to use `fetch` to call an API using query parameters that were read from `location` data, and then render that data client-side once the server responds! Neato!

The one thing you might notice when loading the page is that while the page rendering is pretty quick, there’s a bit of a delay in loading the actual information from the serverless function created by Vercel, hence our page says “Loading…” first before getting the actual greeting. I will say that this is one thing that Next.js does pretty well that Gatsby does not: all pages in Gatsby are static, whereas Next.js can actually create _lambdas_ of pages, so the loading and rendering of the data is handled server-side. If we were using Next.js, we could use it’s [`getServerSideProps`](https://nextjs.org/docs/basic-features/data-fetching#getserversideprops-server-side-rendering) API to render everything server-side so that the client doesn’t have to load any data itself. No need for loading indicators.

## Conclusion

Hopefully you’ve found some of this information useful! As always, links to my social media are located below if you want to ask questions about this post or if you want to suggest a future post. Thanks for reading!