Loading...
Loading...
Use when building REST API endpoints, server-side data processing, or backend HTTP handlers. Use only when the user specifically asks for a backend endpoint. Triggers include API, endpoint, backend, server route, HTTP methods, CRUD operations, data mutations, server-side validation, form handling.
npx skill4agent add wix/skills wix-cli-backend-api.tssrc/pages/api/.tsGETPOSTPUTDELETEPATCHAPIRouteResponsesrc/pages/api/users.ts → /api/userssrc/pages/api/users/[id].ts → /api/users/:id
src/pages/api/posts/[slug].ts → /api/posts/:slug
src/pages/api/users/[userId]/posts/[postId].ts → /api/users/:userId/posts/:postIdAPIRouteimport type { APIRoute } from "astro";
export async function GET({ params, request }) {
// Handle GET request
}
export async function POST({ params, request }) {
// Handle POST request
}
export async function PUT({ params, request }) {
// Handle PUT request
}
export async function DELETE({ params, request }) {
// Handle DELETE request
}
export async function PATCH({ params, request }) {
// Handle PATCH request
}paramsexport async function GET({ params }) {
const { id } = params; // From /api/users/[id]
if (!id) {
return new Response(JSON.stringify({ error: "ID required" }), {
status: 400,
statusText: "Bad Request",
headers: { "Content-Type": "application/json" },
});
}
// Use id to fetch data
}request.urlnew URL(request.url).searchParamsexport async function GET({ request }) {
const url = new URL(request.url);
const search = url.searchParams.get("search");
const limit = parseInt(url.searchParams.get("limit") || "10", 10);
const offset = parseInt(url.searchParams.get("offset") || "0", 10);
// Use query parameters
}request.urlnew URL(request.url).searchParamsexport async function POST({ request }) {
try {
const body = await request.json();
const { title, content } = body;
// Validate required fields
if (!title || !content) {
return new Response(
JSON.stringify({ error: "Title and content required" }),
{
status: 400,
statusText: "Bad Request",
headers: { "Content-Type": "application/json" },
}
);
}
// Process data
} catch (error) {
return new Response(JSON.stringify({ error: "Invalid JSON" }), {
status: 400,
statusText: "Bad Request",
headers: { "Content-Type": "application/json" },
});
}
}export async function GET({ request }) {
const authHeader = request.headers.get("Authorization");
const contentType = request.headers.get("Content-Type");
// Use headers
}ResponseJSON.stringify()return new Response(JSON.stringify({ data: result }), {
status: 200,
headers: {
"Content-Type": "application/json",
},
});return new Response(JSON.stringify({ id: newId, ...data }), {
status: 201,
headers: {
"Content-Type": "application/json",
},
});// Bad Request (400)
return new Response(JSON.stringify({ error: "Invalid input" }), {
status: 400,
statusText: "Bad Request",
headers: { "Content-Type": "application/json" },
});
// Not Found (404)
return new Response(JSON.stringify({ error: "Resource not found" }), {
status: 404,
statusText: "Not Found",
headers: { "Content-Type": "application/json" },
});
// Internal Server Error (500)
return new Response(JSON.stringify({ error: "Internal server error" }), {
status: 500,
statusText: "Internal Server Error",
headers: { "Content-Type": "application/json" },
});@wix/dataimport { items } from "@wix/data";
export async function GET({ params }) {
const { id } = params;
try {
if (id) {
// Get single item
const item = await items.get("collectionId", id);
return new Response(JSON.stringify(item), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} else {
// Get all items
const results = await items.query("collectionId").limit(50).find();
return new Response(JSON.stringify(results.items), {
status: 200,
headers: { "Content-Type": "application/json" },
});
}
} catch (error) {
return new Response(JSON.stringify({ error: "Failed to fetch data" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
export async function POST({ request }) {
try {
const body = await request.json();
const newItem = await items.insert("collectionId", body);
return new Response(JSON.stringify(newItem), {
status: 201,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
return new Response(JSON.stringify({ error: "Failed to create item" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
export async function PUT({ params, request }) {
const { id } = params;
if (!id) {
return new Response(JSON.stringify({ error: "ID required" }), {
status: 400,
statusText: "Bad Request",
headers: { "Content-Type": "application/json" },
});
}
try {
const body = await request.json();
const updatedItem = await items.update("collectionId", {
_id: id,
...body,
});
return new Response(JSON.stringify(updatedItem), {
status: 200,
headers: { "Content-Type": "application/json" },
});
} catch (error) {
return new Response(JSON.stringify({ error: "Failed to update item" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}
export async function DELETE({ params }) {
const { id } = params;
if (!id) {
return new Response(JSON.stringify({ error: "ID required" }), {
status: 400,
statusText: "Bad Request",
headers: { "Content-Type": "application/json" },
});
}
try {
await items.remove("collectionId", id);
return new Response(null, {
status: 204,
});
} catch (error) {
return new Response(JSON.stringify({ error: "Failed to delete item" }), {
status: 500,
headers: { "Content-Type": "application/json" },
});
}
}eqnegtgeltlebetweencontainsstartsWithendsWithhasSomehasAllisEmptyisNotEmptyandornotascendingdescendinglimitskipincludesrc/pages/api/
├── users.ts # /api/users endpoint
├── users/
│ └── [id].ts # /api/users/:id endpoint
└── posts.ts # /api/posts endpointsrc/pages/api/anyAPIRouteResponseJSON.stringify()Content-Type: application/jsonstatusText@ts-ignore