http - using server actions with route handlers when making NextJS API endpoints - Stack Overflow

I have a web app that needs to expose APIs for mobile app (GET, POST, PUT AND DELETE endpoints), curren

I have a web app that needs to expose APIs for mobile app (GET, POST, PUT AND DELETE endpoints), currently i'm doing the fetch in both client and server components, but i looked at the client components and thought why wouldn't i make server actions for these fetches so it would be executed on the server rather than client and therefore it reduces Javascript, so i did it and it worked !, but i don't seem to understand how it even works, i have a route handler PUT method, but server actions use the POST method, does that mean the route handler endpoints will lose their HTTP method and it will all be POST and how is this not the case ?

and if server actions are executed on the server, then how can they use fetch which is only available in the browser ?

clientComponent

  const handleEdit = async () => {
    if (validateRow(editingRow)) {
      try {
        const updatedItem = await editRow(
          locale,
          apiEndpoint,
          editingId,
          editingRow
        ); // Use Server Action
        setData(
          data.map((item) =>
            item.id === editingId ? { ...item, ...updatedItem } : item
          )
        );
        cancelEditing();
      } catch (error) {
        console.error("Error updating item:", error);
      }
    }
  };

server action

"use server";

export async function editRow(locale, apiEndpoint, id, updatedRow) {
  try {
    const response = await fetch(
      `http://localhost:3000/${locale}/${apiEndpoint}/api/${id}`,
      {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(updatedRow),
      }
    );

    if (response.ok) {
      return await response.json();
    } else {
      throw new Error("Failed to update item");
    }
  } catch (error) {
    console.error("Error updating item:", error);
    throw error;
  }
}

api/route.js

export async function PUT(request, { params }) {
  const t = await getTranslations("HomePage");
  const { package_name, package_description, package_price } =
    await request.json();
  const { id } = await params;
  if (!id || !package_name || !package_price || !package_description) {
    return Response.json(
      { message: "Missing required fields" },
      { status: 400 }
    );
  }

  try {
    await db(
      "UPDATE packages SET package_name = ?, package_description = ?, package_price = ? WHERE id = ?",
      [package_name, package_description, package_price, id]
    );

    return Response.json(
      { message: "Package updated successfully" },
      { status: 200 }
    );
  } catch (error) {
    return Response.json({ message: t("somethingWrong") }, { status: 500 });
  }
}

I have a web app that needs to expose APIs for mobile app (GET, POST, PUT AND DELETE endpoints), currently i'm doing the fetch in both client and server components, but i looked at the client components and thought why wouldn't i make server actions for these fetches so it would be executed on the server rather than client and therefore it reduces Javascript, so i did it and it worked !, but i don't seem to understand how it even works, i have a route handler PUT method, but server actions use the POST method, does that mean the route handler endpoints will lose their HTTP method and it will all be POST and how is this not the case ?

and if server actions are executed on the server, then how can they use fetch which is only available in the browser ?

clientComponent

  const handleEdit = async () => {
    if (validateRow(editingRow)) {
      try {
        const updatedItem = await editRow(
          locale,
          apiEndpoint,
          editingId,
          editingRow
        ); // Use Server Action
        setData(
          data.map((item) =>
            item.id === editingId ? { ...item, ...updatedItem } : item
          )
        );
        cancelEditing();
      } catch (error) {
        console.error("Error updating item:", error);
      }
    }
  };

server action

"use server";

export async function editRow(locale, apiEndpoint, id, updatedRow) {
  try {
    const response = await fetch(
      `http://localhost:3000/${locale}/${apiEndpoint}/api/${id}`,
      {
        method: "PUT",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(updatedRow),
      }
    );

    if (response.ok) {
      return await response.json();
    } else {
      throw new Error("Failed to update item");
    }
  } catch (error) {
    console.error("Error updating item:", error);
    throw error;
  }
}

api/route.js

export async function PUT(request, { params }) {
  const t = await getTranslations("HomePage");
  const { package_name, package_description, package_price } =
    await request.json();
  const { id } = await params;
  if (!id || !package_name || !package_price || !package_description) {
    return Response.json(
      { message: "Missing required fields" },
      { status: 400 }
    );
  }

  try {
    await db(
      "UPDATE packages SET package_name = ?, package_description = ?, package_price = ? WHERE id = ?",
      [package_name, package_description, package_price, id]
    );

    return Response.json(
      { message: "Package updated successfully" },
      { status: 200 }
    );
  } catch (error) {
    return Response.json({ message: t("somethingWrong") }, { status: 500 });
  }
}
Share Improve this question asked Mar 16 at 21:14 Aasem ShoshariAasem Shoshari 431 silver badge6 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

The server action works by submitting the actual arguments of your server action function, editRow, to the server. You can see the network traffic using the "Network" panel in the DevTools of the browser. It should be a POST request with an array of the values of [locale, apiEndpoint, id, updatedRow]. After the server gets the values of the arguments, it will execute the editRow function, which calls the fetch() of the NodeJS environment (on the server).

Here is an illustration:

Source: A Year with Next.js Server Actions: Lessons Learned

As you can see in this figure, NextJS performs internal serialization and de-serialization of your data. Thus, I would suggest you to refactor the code JSON.stringify(updatedRow) from the server side to the client side.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744586057a4582317.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信