Next.js Discord

Discord Forum

405 Not Allowed

Answered
Western yellowjacket posted this in #help-forum
Open in Discord
Western yellowjacketOP
Hello,

I'm fairly new to NextJS, I've done a frontend website using it but this is the first time that I connected it into a database. Right now, I'm getting the 405 error when I'm trying to fetch the data from MongoDB. I'll provide the API and frontend code for it below. I hope someone can assist me on this. I already tried searching for answers online but it's outdated even ChatGPT is outdated regarding NextJS.

API:
import { PrismaClient } from "@prisma/client";
import Cors from "cors";

const prisma = new PrismaClient();

const cors = Cors({
  methods: ["GET", "HEAD"],
  origin: "*",
  optionsSuccessStatus: 200,
});

export default async function GET(req) {
  // Run cors
  await cors(req, res);

  if (req.method !== "GET") {
    return res.status(405).end(); // Method Not Allowed
  }

  try {
    const users = await prisma.user.findMany();
    return res.status(200).json(users);
  } catch (error) {
    console.error("Error fetching users:", error);
    return res.status(500).json({ error: "Internal Server Error" });
  }
}


Here is how I'm trying to output the data:
const [users, setUsers] = useState([]);

  useEffect(() => {
    async function fetchUsers() {
      try {
        const response = await fetch("/api/users"); // Change the API endpoint to match your actual API route
        if (response.ok) {
          const data = await response.json();
          setUsers(data);
        } else {
          console.error("Error fetching users:", response.statusText);
        }
      } catch (error) {
        console.error("Error fetching users:", error);
      }
    }

    fetchUsers();
  }, []);
Answered by fuma
Oops, you can't export default, instead, export async function GET
View full answer

29 Replies

Where do the res comes from? in API Handler, you have to use NextResponse rather than res
return NextResponse.json({ ... }, { status: 2000 });

Also, you don't need to check the method and return 405 anymore.

If you can already connect your database with Prisma ORM, it should work
@fuma Where do the `res` comes from? in API Handler, you have to use `NextResponse` rather than `res` ts return NextResponse.json({ ... }, { status: 2000 }); Also, you don't need to check the method and return `405` anymore. If you can already connect your database with Prisma ORM, it should work
Western yellowjacketOP
The res just came from online, I tried chatgpt to find some answers but it's pretty outdated and giving me those codes when I ask regarding the issue. The code API has a mixed of online articles I found then chatgpt haha. But I'll try that!
If you want to learn more, read this:
https://nextjs.org/docs/app/building-your-application/routing/route-handlers

The way you connect with the database is probably correct since you're using Prisma, I believe it's harder to done it wrong.
@fuma If you want to learn more, read this: https://nextjs.org/docs/app/building-your-application/routing/route-handlers The way you connect with the database is probably correct since you're using Prisma, I believe it's harder to done it wrong.
Western yellowjacketOP
Alright! I'll check that out! Thank you!

Yea it can connect to the database with no problem since I can send a POST request to it. I'm just having a hard time retrieving the data I posted and put it on a list
Western yellowjacketOP
I'm still getting the 405 error and this is showing on my console:

- error No HTTP methods exported in '/home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/app/api/users/route.js'. Export a named export for each HTTP method.


😦
I also tried modifying the API to this:
import { PrismaClient } from "@prisma/client";
import { NextResponse } from "next/server";

const prisma = new PrismaClient();

export default async function GET() {
  try {
    const users = await prisma.user.findMany();
    console.log("Users:", users);
    return new NextResponse.json("Users: " + JSON.stringify(users), {
      status: 200,
    });
  } catch (error) {
    console.error("Error fetching users:", error);
    return new NextResponse("Error fetching users", { status: 500 });
  }
}
Oops, you can't export default, instead, export async function GET
Answer
Western yellowjacketOP
aaah! I'll try that!
@fuma Oops, you can't `export default`, instead, `export async function GET`
Western yellowjacketOP
that worked! It is now logging the data in the console. Thank you! Now just need to show it in my frontend. Thank you @fuma!
Western yellowjacketOP
Hello! I'm sorry for opening this again, but I got the same error when I'm trying to delete a user. I'm getting the 405 error.

This is the API:
export async function DELETE(request, { params }) {
  try {
    const { id } = params;

    const user = await prisma.user.delete({
      where: {
        id,
      },
    });

    return new NextResponse(JSON.stringify(user), {
      status: 200,
    });
  } catch (error) {
    console.error("Error deleting user:", error);
    return new NextResponse("Error deleting user", { status: 500 });
  }
}


Then this is the one in the frontend:
const handleDelete = async (id) => {
    try {
      const response = await fetch(`/api/users/${id}`, {
        method: "DELETE",
      });
      if (response.ok) {
        const data = await response.json();
        setUsers(data);
      } else {
        console.error("Error deleting user:", response.statusText);
      }
    } catch (error) {
      console.error("Error deleting user:", error);
    }
  };

<Button onClick={() => {handleDelete(user.id)}} colorScheme="red">
 Delete
</Button>


I already tried searching online for a any solutions but it doesn't really help 😦
Western yellowjacketOP
everytime I click the delete button it will just give the 405 error. I'm just not sure what is preventing it to proceed
I also tried it with axios but it's giving the same error
Western yellowjacketOP
I've already double checked the documentations I can find, I can't figure out what I missed :/
@fuma I can't reproduce the problem Your code seems to be correct, the following worked for me: js export async function DELETE(request) { return NextResponse.json({ message: "Hello World" }, { status: 200 }); } js fetch("/api/test", { method: "DELETE" })
Western yellowjacketOP
That's weird :/ idk why it is doing it then :/ I created a gist for it here:
https://gist.github.com/NexCodeJimM/8c402d700bcc90bde9364a992b0552c6

It's the whole code for the route and page.jsx file. Idk if that will help on anything :/ but the user fetching works fine, but not the delete :/
You can ignore the axios part, I tried axios and it doesn't work as well :/
should I try separating the DELETE and GET? like call delete from a different file? But idk if that will even work xD
Western yellowjacketOP
Yea I tried the other file thing, didn't work either xD
if it doesn't work you probably need to make a reproduction repository
@joulev the only issue i can find with this is that it should be `export async function DELETE(request, { params })` not `export async function DELETE({ params })`
Western yellowjacketOP
It actually has request before I started to try troubleshooting it but it still doesn't want to work unfortunately.

But if you want to see the repo, I just published it here:
https://github.com/NexCodeJimM/findeb-me-dashboard
@Western yellowjacket It actually has `request` before I started to try troubleshooting it but it still doesn't want to work unfortunately. But if you want to see the repo, I just published it here: https://github.com/NexCodeJimM/findeb-me-dashboard
can you make a more simplified version? i can't debug on repositories that are too complex to set-up quickly (e.g. repositories with auth/db/env vars)
Hold up, I guess it's your little mistake.
Where is your DELETE function? Is it inside of /api/users/[id]/route.ts?
I only found a DELETE handler in [/api/users/route.ts](https://github.com/NexCodeJimM/findeb-me-dashboard/blob/main/app/api/users/route.js) but you're calling /api/users/${id} rather than /api/users in the client side.
@fuma Hold up, I guess it's your little mistake. Where is your `DELETE` function? Is it inside of `/api/users/[id]/route.ts`?
Western yellowjacketOP
The delete function is in /api/users If I changed it to to /api/users it is just giving me a 500 Error
@fuma Hold up, I guess it's your little mistake. Where is your `DELETE` function? Is it inside of `/api/users/[id]/route.ts`?
Western yellowjacketOP
I think I get what you meant now.

I just modified the API to this:
export async function DELETE(request) {
  const { id } = await request.json();
  try {
    const user = await prisma.user.delete({
      where: {
        id,
      },
    });
    if (!user) {
      return new NextResponse("User not found", { status: 404 });
    }
    return new NextResponse(JSON.stringify(user), {
      status: 200,
    });
  } catch (error) {
    return new NextResponse("Error deleting user", { status: 500 });
  }
}


Then I changed my frontend to this:
const handleDelete = async () => {
    try {
      const response = await fetch("/api/users/", {
        method: "DELETE",
      });

      if (response.ok) {
        const data = await response.json();
        setUsers(data);
      } else {
        console.error("Error deleting user:", response.statusText);
      }
    } catch (error) {
      console.error("Error deleting user:", error);
    }
  };

<Button onClick={() => {handleDelete();}} colorScheme="red" fontSize="sm">
   Delete
</Button>


Basically I was wanting to delete the data from the table directly.

Then it will just show me this error upon pressing Delete
- error SyntaxError: Unexpected end of JSON input
    at JSON.parse (<anonymous>)
    at parseJSONFromBytes (/home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/node_modules/next/dist/compiled/undici/index.js:2:4905)
    at successSteps (/home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/node_modules/next/dist/compiled/undici/index.js:2:4473)
    at /home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/node_modules/next/dist/compiled/undici/index.js:2:65581
    at node:internal/process/task_queues:141:7
    at AsyncResource.runInAsyncScope (node:async_hooks:203:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:138:8)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (node:internal/process/task_queues:96:5)


Btw thank you for helping me! I really do apologize for being a pain :mild_panic:
Because you need the parameter, just put it in /api/users/[id]/route so that you can receive the parameter via params
@Western yellowjacket I think I get what you meant now. I just modified the API to this: export async function DELETE(request) { const { id } = await request.json(); try { const user = await prisma.user.delete({ where: { id, }, }); if (!user) { return new NextResponse("User not found", { status: 404 }); } return new NextResponse(JSON.stringify(user), { status: 200, }); } catch (error) { return new NextResponse("Error deleting user", { status: 500 }); } } Then I changed my frontend to this: const handleDelete = async () => { try { const response = await fetch("/api/users/", { method: "DELETE", }); if (response.ok) { const data = await response.json(); setUsers(data); } else { console.error("Error deleting user:", response.statusText); } } catch (error) { console.error("Error deleting user:", error); } }; <Button onClick={() => {handleDelete();}} colorScheme="red" fontSize="sm"> Delete </Button> Basically I was wanting to delete the data from the table directly. Then it will just show me this error upon pressing `Delete` - error SyntaxError: Unexpected end of JSON input at JSON.parse (<anonymous>) at parseJSONFromBytes (/home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/node_modules/next/dist/compiled/undici/index.js:2:4905) at successSteps (/home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/node_modules/next/dist/compiled/undici/index.js:2:4473) at /home/ubuntu/development/web-development/clients/FINDEB/findeb-me-dashboard/node_modules/next/dist/compiled/undici/index.js:2:65581 at node:internal/process/task_queues:141:7 at AsyncResource.runInAsyncScope (node:async_hooks:203:9) at AsyncResource.runMicrotask (node:internal/process/task_queues:138:8) at runMicrotasks (<anonymous>) at processTicksAndRejections (node:internal/process/task_queues:96:5) Btw thank you for helping me! I really do apologize for being a pain <:mild_panic:770004383886737418>
And code above is quite confusing, how do you even pass the user id from client side? You have to add it into the body:
body: JSON.stringify({ id })
Otherwise, request.json() fails because the body is empty