Swizec Teller - a geek with a hatswizec.com

Senior Mindset Book

Get promoted, earn a bigger salary, work for top companies

Senior Engineer Mindset cover
Learn more

    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

    PS: since this article was published, Gatsby added /api routes too 🥳

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

    Did you enjoy this article?

    Continue reading about Why NextJS /api routes are fab – CodeWithSwiz 6

    Semantically similar articles hand-picked by GPT-4

    Senior Mindset Book

    Get promoted, earn a bigger salary, work for top companies

    Learn more

    Have a burning question that you think I can answer? Hit me up on twitter and I'll do my best.

    Who am I and who do I help? I'm Swizec Teller and I turn coders into engineers with "Raw and honest from the heart!" writing. No bullshit. Real insights into the career and skills of a modern software engineer.

    Want to become a true senior engineer? Take ownership, have autonomy, and be a force multiplier on your team. The Senior Engineer Mindset ebook can help 👉 swizec.com/senior-mindset. These are the shifts in mindset that unlocked my career.

    Curious about Serverless and the modern backend? Check out Serverless Handbook, for frontend engineers 👉 ServerlessHandbook.dev

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

    Want to get my best emails on JavaScript, React, Serverless, Fullstack Web, or Indie Hacking? Check out swizec.com/collections

    Did someone amazing share this letter with you? Wonderful! You can sign up for my weekly letters for software engineers on their path to greatness, here: swizec.com/blog

    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 ❤️

    Created by Swizec with ❤️