I built an Harry Potter⚡ API, so you dont have to
Zeeshan

Zeeshan @acidop

About: Known to beat my keyboard until some useful code comes up. 2k followers | 18k+ views 👀

Location:
India
Joined:
Oct 3, 2022

I built an Harry Potter⚡ API, so you dont have to

Publish Date: Jun 16 '23
40 10

Hello World!

Now before you scoff and say, "What on Earth would you need a Harry Potter API for?" hear me out. We Potterheads love the intricate tapestry of spells, characters, houses, books, and movies. So, naturally, it got me thinking, "Wouldn't it be amazing to have an API that provides all this enchanting data?!"

3 days and almost 10 coffees later I have everything ready.

What we're building 🤔

Let's create an API that sends data about the following from the franchise:

  • Characters
  • Spells
  • Houses
  • Books
  • Movies

At the end I'll also tell you why I had to bang my head on wall for a mistake 🤏 this big, that caused a bug on production.

Setting up the project

I used NextJS for this because that is my goto for every web development project.

Almost everyone knows how to setup a Nextjs project so I'm not explaining it however you can follow this if you don't know how to.

Next I stole open sourced data from KostaSav and Daniel. And put them inside a folder called db inside project root.

Creating API Routes

In NextJS 13 the way API works has completely changed. In order to get APIs working follow the below steps:

  1. Inside the app dir create a folder called api. Not necessarily api you can also use your name for the folder and it will still work, unlike Next 12. But for simplicity we will use api.
  2. Create a folder called characters and finally inside it create a file called route.ts. The route.ts will be the entry to the /api/characters path. It is similar to what index.html is (entry point).
  3. Inside characters folder create another folder called [characters] followed by another route.ts. This will catch all dynamic routes. e.g. /api/characters/harry%20potter
  4. Repeat the above steps for houses, spells, books, movies.

Next 13 APIs (Important)

For an API to work in Next 13 we need to follow this syntax:

// For GET requests
export async function GET() {
  return new Response("Hello");
}

// For POST requests
export async function POST() {
  return new Response("World");
}

// To get slug follow this
export async function GET(
    { params }: { params: { character: string } }
) {
  const { character } = params;
  return new Response(character);
}
Enter fullscreen mode Exit fullscreen mode

Check out their documentation here.

Setting up the APIs

  • /api/characters

This route sends json containing data about characters from the Franchise. So we need to read the data from db/characters.json, convert into a JSON string and send it.

import characters from "@/db/characters.json";

export async function GET() {
  return new Response(JSON.stringify(characters), {
    headers: { "content-type": "application/json" },
  });
}
Enter fullscreen mode Exit fullscreen mode
  • /api/characters/[character]

This is a bit complicated.

Dynamic Route which will send data about an individual character.
For this we need to get the slug from URL.

So if your folder is named [character], inside the GET method you need to pass the following parameter:

import characters from "@/db/characters.json";

export async function GET(
  { params }: { params: { character: string } }
  // I totally understand this line I swear

  const { character } = params; // Ah finally the slug
)
Enter fullscreen mode Exit fullscreen mode

Next we need to find the character from the slug in our JOSN file.

if (character) {
    const characterString = characters.find(
      (c) => c.name.toLowerCase() === character.toLowerCase()
    );
    
    if (characterString) {
      return new Response(JSON.stringify(characterString), {
        headers: { "content-type": "application/json" },
      });
    }
  }
Enter fullscreen mode Exit fullscreen mode

Finally if no such character exists in the database, return a message saying the same.

return new Response(`No character with name ${character}`);
Enter fullscreen mode Exit fullscreen mode

So at the end your code will look somewhat like this:

import characters from "@/db/characters.json";

export async function GET(
  request: Request,
  { params }: { params: { character: string } }
) {
  const { character } = params;

  if (character) {
    const characterString = characters.find(
      (c) => c.name.toLowerCase() === character.toLowerCase()
    );

    if (characterString) {
      return new Response(JSON.stringify(characterString), {
        headers: { "content-type": "application/json" },
      });
    }
  }
  return new Response(`No character with name ${character}`);
}
Enter fullscreen mode Exit fullscreen mode
  • Repeat the above steps for houses, spells, books, movies.

The Error

And about the error I talked about in the first part...

So I used TailwindCSS for the frontend and for some reason it just wasn't working when pushed on Vercel. So I had to spend a good part of my day just to find out that my tailwind config had a misconfiguration. So basically I wrote components instead of Components 😑.
Just 1 letter caused me so much trouble.

Finally...

This is just a quick rundown of a 4 days journey and around 10 cups coffee.

Please checkout the Live Demo and here is the Github Repo

Like

If you enjoyed the API please give a 💖 and 🌟 the Github repo.

Comments 10 total

  • Femi Akinyemi
    Femi AkinyemiJun 16, 2023

    Thanks for building this and sharing👍🏾

    • Zeeshan
      ZeeshanJun 17, 2023

      Thanks for giving it a read 😀

  • lionel-rowe
    lionel-roweJun 19, 2023
      return new Response(`No character with name ${character}`);
    

    Seems like a classic 404 Not Found error. You can specify a status code for Response objects like this:

      return new Response(`No character with name ${character}`, {
        status: 404,
      });
    
    Enter fullscreen mode Exit fullscreen mode

    If you don't specify a status code, it defaults to 200 OK, so consumers of your API won't be able to determine whether the request actually succeeded without parsing the response body (or worse, they'll have no way of determining success at all, in the case of a HEAD request).

    • Zeeshan
      ZeeshanJun 20, 2023

      Thanks for your input. I was in a hurry to just complete this project so I missed on these small details 😅.

      I will update it for sure! Thanks!

  • Ashish Khare😎
    Ashish Khare😎Jun 19, 2023

    Thanks for the outline. Also, I've once also faced the same error.
    Npm doesn't allow uppercase as naming convention.
    Now I'm of to make an API for naruto.
    Datte-byo!

  • Aaron McCollum
    Aaron McCollumJun 19, 2023

    This is awesome. This caught my eye as I really enjoy Harry Potter. Just 10 coffees though?!? Impressive haha

    • Zeeshan
      ZeeshanJun 20, 2023

      Haha thanks for giving it a read 💖

  • zee914
    zee914Jul 6, 2023

    hey you have done such a great work i am die heart fan of harry potter me and my dog with a cup of tea enjoyed this master piece alote.

    • Zeeshan
      ZeeshanJul 11, 2023

      glad to know! 😄

Add comment