Swizec Teller - a geek with a hatswizec.com

    You are allowed to invent HTTP status codes

    Here's my 2nd favorite frustration with RESTful APIs, one where I spent the first 10 years of my career valiantly arguing for the wrong side.

    You make a request. It returns 404 Not Found. What's wrong?

    https://twitter.com/Swizec/status/1533934323136573441

    Everything an error may mean

    You may be requesting a resource that doesn't exist. Server looked in the database, found nothing, returned 404. As expected.

    You may be requesting an API route that doesn't exist. Server got the request, couldn't figure out where it goes, returned 404. As ... expected?

    You may be requesting a domain that isn't configured. Server got the request, couldn't find the application, returned 404. Rare because DNS won't return 404, but it can happen.

    Any number of intermediary servers (proxies, VPNs, CDNs, NATs, etc) between your browser and your API may return a 404 Not Found. For any "didn't find the thing" reason.

    The response can even get cached along the way. You'll get 404 for a few seconds even after you fix routing on the server 💩

    Protocol vs application level errors

    HTTP Status Codes work just fine. Use them.

    The problem you're facing is that traditional RESTful design mixes domains between protocol and application errors.

    You can't tell the difference between an error that happened on the way to your server, in your server, or inside your business logic. Is it really the same error when you can't find a user and when you typo'd the path? 🤔

    Feels different doesn't it ...

    That's why many modern APIs have started returning 200 Success for everything. As long as the server machinery works.

    Status: 200
    {
    error: 'Not Found'
    }

    GraphQL does this – everything is a POST and gets a 200 response. Even if your app breaks down. As long as the app itself is responding, you get a 200.

    Some RESTful APIs do it too.

    An elegant (and evil?) solution

    200 Not Found feels weird to me.

    I understand the reasoning and dislike that nobody except your very special custom client understands there was an error. This can lead to over-aggressive caching from other servers in the chain.

    Imagine a CDN that caches a 200 Not Found. Fix all you want, CDN won't check with your server for 3 days 💩

    You can use additional headers that explain why a 404 happened. Good approach. Can be cumbersome.

    OR! You can invent a custom HTTP status code.

    Custom HTTP status code

    The idea is not as crazy as it sounds. I checked.

    Internet says it's okay
    Internet says it's okay

    In the 4xx space, status codes 452-499 are unassigned and free to use for your nefarious means.

    The ergonomics of a custom error code are great:

    async function example() {
    const res = await fetch("https://example.com/some/api")
    if (!res.ok) {
    if (res.status === 493) {
    throw new Error("Server said 493 not cool enough")
    }
    }
    return res.json()
    }

    Because your status code is in the 4xx space, every piece of web machinery knows the client made a bad request. They won't know what kind, but they do know it failed.

    You'll see it as an error in server logs too. Because that machinery knows it's an error.

    And it won't get unexpectedly cached. Because caches know it's an error and cache less aggressively.

    Even your browser shows it as a helpful error when debugging.

    Browser dev tools recognize the error
    Browser dev tools recognize the error

    The major downside

    Inventing HTTP status codes of your own comes with one major downside:

    What if the HTTP protocol starts using your code in the future? Then you're back to not knowing the difference and your status code is wrong.

    But HTTP moves slow 🤞

    Cheers,
    ~Swizec

    PS: APIs may return 404 on unauthenticated requests for security reasons. They don't want to reveal whether something exists, unless you're allowed to know. GitHub does this.

    Did you enjoy this article?

    Published on June 7th, 2022 in Backend, Fullstack, REST,

    Want to become a Fullstack Web expert?

    Learning from tutorials is great! You follow some steps, learn a smol lesson, and feel like you got this. Then you go into an interview, get a question from the boss, or encounter a new situation and o-oh.

    Shit, how does this work again? 😅

    That's the problem with tutorials. They're not how the world works. Real software is a mess. A best-effort pile of duct tape and chewing gum. You need deep understanding, not recipes.

    Leave your email and get the Fullstack Web Essays series - a series of curated essays and experiments on modern Fullstack Web development. Lessons learned from practice building production software.

    Curated Fullstack Web Essays

    Get a series of curated essays on Fullstack Web development. Lessons and insights from building software for production. No bullshit.

    Join 15,883+ engineers learning lessons from my "raw and honest from the heart" emails.

    ⭐️⭐️⭐️⭐️✨
    4.5 stars average rating

    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

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

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