With Payload CMS 3.0, the platform no longer provides built-in support for PATCH operations through the GraphQL or REST API. This can be limiting when you want to partially update a document without overwriting the entire object (which is typically what PUT or POST operations do).
To address this, you’ve created a custom API route in your Next.js app that:
- Accepts only
POSTorPUTmethods. - Internally converts those requests into
PATCHoperations by: - Extracting the
idof the document to update. - Forwarding the update payload to a constructed PATCH endpoint:
https://your-domain.com/api/[collection]/[id]- Using
fetch()to call the Payload API directly with method"PATCH". - Includes necessary headers like
AuthorizationandContent-Type.
This workaround helps you simulate PATCH functionality while using methods still allowed by your client logic (POST or PUT), ensuring only changed fields are updated.
import type { NextApiRequest, NextApiResponse } from "next";
import { GRAPHQL_API_URL } from "@/_api/shared";
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
const {
method,
body,
query: { collection }
} = req;
// Allow only POST or PUT
if (method !== "POST" && method !== "PUT") {
res.setHeader("Allow", ["POST", "PUT"]);
return res.status(405).json({ success: false, message: `Method ${method} Not Allowed` });
}
const { id, ...updateData } = body;
if (!id || typeof updateData !== "object" || typeof collection !== "string") {
return res.status(400).json({
success: false,
message: "Missing 'id', 'collection', or invalid update payload"
});
}
const patchUrl = `${GRAPHQL_API_URL}/api/${collection}/${id}`;
try {
const response = await fetch(patchUrl, {
method: "PATCH",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.PAYLOAD_API_KEY || ""}`
},
body: JSON.stringify(updateData)
});
const result = await response.json();
if (!response.ok) {
throw new Error(result.message || "PATCH failed");
}
return res.status(200).json({
success: true,
message: `Updated '${collection}' record.`,
data: result
});
} catch (err: any) {
console.error("PATCH error:", err);
return res.status(500).json({
success: false,
message: err.message || "Server Error"
});
}
}