Using Gatsby Serverless Functions as an abstracted API
They’re here! Gatsby Serverless 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 Serverless Functions.
Here’s how I did it. 👇
- 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:
- twitter-user: https://paulieapi.gatsbyjs.io/api/twitter-user
- github-user: https://paulieapi.gatsbyjs.io/api/github-user
To use Gatsby Serverless Functions have a read of the Getting Started docs but i’ll break down the steps you’ll probably need to use Gatsby Serverless Functions anyway
Install Dependencies
You’ll need Gatsby 3.4.0
or higher installed
npm install gatsby@latest
Enable Feature Flag
Gatsby Serverless 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👇
Small tweak: with Gatsby 3.7, you no longer need the flag in gatsby-config!
— Joel Smith (@jsumnersmith) June 11, 2021
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 Serverless Functions in an abstracted and potentially easily incrementally adoptable way. — jeez what a sentence! 🕺