Using Gatsby Functions as an abstracted API-image

Using Gatsby Functions as an abstracted API

Date published: 11-Jun-2021
2 min read / 406 words
Author: Paul Scanlon

React
Gatsby
Gatsbv Functions
JavaScript
Gatsby Plugins

They're here! Gatsby Functions are here! They're finally here! 💝 -- And I couldn't be more excited!

A little while ago I wrote a post about using the Twitter API as a kind of CMS for my blog. You can read more about that here: Use Netlify Functions and the Twitter API v2 as a CMS for your Gatsby blog

In short I created my own mini API that is used by both my commercial portfolio: https://www.pauliescanlon.io and my blog: https://paulie.dev to display my current Twitter bio information on the home page(s).

Both my sites are built on top of my Gatsby theme gatsby-theme-terminal which I haven't updated to Gatsby v3.x.x yet, and both sites are currently hosted by Netlify... but I didn't want that to hold me up from adopting Gatsby Functions.

Here's how I did it. 👇

API

  • demo: https://paulieapi.gatsbyjs.io/
  • source code: https://github.com/PaulieScanlon/paulie-api,

My API is actually a very simple Gatsby Site deployed on Gatsby Cloud. It displays the response from my endpoints in HTML <pre> tags. This isn't entirely necessary but it allows me to test a request and preview the responses in an almost real and un-abstracted way.

You can also see the json response for each of my endpoints using the links below:

Functions

To use Gatsby Functions have a read of the Getting Started docs but i'll break down the steps you'll probably need to use Gatsby Functions anyway

Install Dependencies

You'll need Gatsby 3.4.0 or higher installed

npm install gatsby@latest

Enable Feature Flag

Gatsby Functions are still technically in beta so you'll need to add FUNCTIONS as a feature flag in your gatsby-config.js

// gatsby-config.js
module.exports = {
flags: {
FUNCTIONS: true
},
plugins: [...]
}

🚨 News just in from Joel Sumner Smith | Product Manager @Gatsby👇


File System - API

Like with the File System Route API The path to Functions is the same on disk as it would be in browser: E.g src/api/some-function => http(s)://.../api/some-function

Endpoint

I have x2 two endpoints in my API they both work in the same way but here's the twitter-user endpoint

// api/twitter-user.js
const { twitter } = require('../clients') // exports Twitter client
export default async function handler(req, res) {
res.setHeader('Access-Control-Allow-Origin', '*') // YOLO
try {
const { data } = await twitter.get('users/by/username/PaulieScanlon', {
user: {
fields:
'created_at,description,entities,id,location,name,pinned_tweet_id,profile_image_url,protected,public_metrics,url,username,verified,withheld',
},
})
res.status(200).json({
user: data,
})
} catch {
res.status(500).json({
error: 'Ooops server error',
})
}
}

Request

I use fetch to hit my API and set the response in state which is then returned by Jsx.

I fetch the data in the ProfileInfo.js component in both my blog and my site

// Any React component
...
const [twitter, setTwitter] = useState({ user: null })
useEffect(() => {
fetch('https://paulieapi.gatsbyjs.io/api/twitter-user')
.then((response) => {
if (response.status >= 200 && response.status <= 299) {
return response.json()
} else {
throw Error(response.message)
}
})
.then((response) => {
// Save response in state hook
setTwitter(response)
})
.catch((error) => {
// Handle the error
})
}, [])
return (
<div>
{twitter.user ? (
<Fragment>
<h2>Twitter User</h2>
<pre>
<code>{JSON.stringify(twitter.user, null, 2)}</code>
</pre>
</Fragment>
) : null}
</div>
)
...

... and that's pretty much it. I might at some point do something with the GitHub data but I just wanted to share how i'm using Gatsby Functions in an abstracted and potentially easily incrementally adoptable way. -- jeez what a sentence! 🕺

Newsletter

This is a sign-up to Queen Raae's Gatsby Newsletter because I don't really like people, or emails. She'll let you know when I have something new to share!



If you've enjoyed this post I'd love to hear from you: @PaulieScanlon