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
1 Answer
Reset to default 1The 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条)