Skip to content
Swizec Teller - a geek with a hatswizec.com

Why NextJS /api routes are fab – CodeWithSwiz 6

NextJS has built-in support for backend code and wow

CodeWithSwiz is a twice-a-week live show. Like a podcast with video and fun hacking. Focused on experiments. Join live Wednesdays and Sundays

In this episode of CodeWithSwiz, we tried NextJS's support for /api routes – code running on the backend.

Got that working, then my internet died. Couldn't finish the full objective of using an /api route to publish code to GitHub. 💩

Why NextJS /api routes are great

NextJS uses a special /pages/api folder for routes running on the server. Both at compile-time and run-time. Always server side code.

Same file-based routing as your frontend code 👉 put a file there and it's available at <domain>/api/filename. Export a default function from this file and that's your API controller.

// pages/api/publishArticle.js
export default async (req, res) => {
res.status(200).json({ success: true });
};

req is the request object, res is the response object. You read inputs from req and return outputs by modifying res.

Testing an /api route in the browser
Testing an /api route in the browser

You'll be familiar with this pattern, if you've used Express before. The most popular JavaScript backend framework, I believe.

Looks compatible with existing Express middlewares 🤘

Locally these routes work with your development server. Deploy to Vercel and they become cloud functions. AWS Lambdas (I assume) running on each API call. Haven't tried with Netlify.

In short, you get serverless without the pain 😍

How you can use /api to get things done

Unlike the traditional Express approach, NextJS forces you to use these routes as an API. They're meant to return data, not pages.

You want to have this discipline in your project as early as possible. Transitioning later when your team grows hurts. Been working on that transition at dayjob.exe and oof, hella gotchas 😅

On the stream, we created a React Query mutation running off a button click. It sends a POST request to our /api route with the full article.

// components/ShipIt.js
export const ShipIt = ({ article }) => {
const [shipArticle, { status, isLoading }] = useMutation(async () => {
// makes a POST request to the server
return fetch("/api/publishArticle", {
method: "POST",
headers: {
// enables automatic body parsing
"Content-Type": "application/json",
},
body: JSON.stringify(article),
});
});
if (isLoading) {
return <Spinner></Spinner>;
} else {
return <Button onClick={shipArticle}>Ship It</Button>;
}
};

We set up a mutation, show a spinner when it's loading, and a button with a click handler otherwise. Click the button, call the shipArticle method returned from useMutation, execute the fetch() call.

Setting the content-type header tells NextJS to parse POST body as a JSON string. Makes it easier to access values :)

// pages/api/publishArticle.js
export default async (req, res) => {
// req.body.title == article title
// req.body.description == article description
// etc
res.status(200).json({ success: true });
};

Tanner says we can share queries and mutations between frontend and backend. Gonna try that next time ✌️

Using GitHub's REST API to commit files

Original goal was to use an /api route to publish an article. Since they're markdown files in a repo, that means using the GitHub API to make a commit.

We use the @octokit/rest library for that.

Runs in Node.js, which means it works with our NextJS server routes. But it's super complex and hard to figure out.

After much spelunking through the docs, we got an authenticated request working. It required a personal GitHub acces token added to .env.local.

// pages/api/publishArticle.js
import { Octokit } from "@octokit/rest";
const octokit = new Octokit({
auth: process.env.GITHUB_TOKEN,
});
export default async (req, res) => {
const { data } = await octokit.request("/user");
// prints user info
console.log(data);
// ...
};

Instantiates Octokit with your token and requests /user data. Makes the project hardcoded to you, but works. We'd have to add a full authentication system to let anyone else use this.

We figured out how to add files to repositories juuuuust as my internet died.

await octokit.repos.createOrUpdateFileContents;

Join me Wednesday evening and we'll figure out the rest 🤞

Cheers,
~Swizec

Did you enjoy this article?

Published on September 13th, 2020 in CodeWithSwiz, Technical, NextJS, Livecoding

Learned something new?
Want to become a high value JavaScript expert?

Here's how it works 👇

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet 📖right away. After that you'll get thoughtfully written emails every week about React, JavaScript, and your career. Lessons learned over my 20 years in the industry working with companies ranging from tiny startups to Fortune5 behemoths.

Start with an interactive cheatsheet 📖

Then get thoughtful letters 💌 on mindsets, tactics, and technical skills for your career.

"Man, love your simple writing! Yours is the only email I open from marketers and only blog that I give a fuck to read & scroll till the end. And wow always take away lessons with me. Inspiring! And very relatable. 👌"

~ Ashish Kumar

Join over 10,000 engineers just like you already improving their careers with my letters, workshops, courses, and talks. ✌️

Have a burning question that you think I can answer? I don't have all of the answers, but I have some! Hit me up on twitter or book a 30min ama for in-depth help.

Ready to Stop copy pasting D3 examples and create data visualizations of your own?  Learn how to build scalable dataviz components your whole team can understand with React for Data Visualization

Curious about Serverless and the modern backend? Check out Serverless Handbook, modern backend for the frontend engineer.

Ready to learn how it all fits together and build a modern webapp from scratch? Learn how to launch a webapp and make your first 💰 on the side with ServerlessReact.Dev

Want to brush up on your modern JavaScript syntax? Check out my interactive cheatsheet: es6cheatsheet.com

By the way, just in case no one has told you it yet today: I love and appreciate you for who you are ❤️