Astro API Endpoints — Server-Side JSON and Form Handling
In this tutorial, you will learn about Astro API Endpoints. We cover key concepts, practical examples, and best practices to help you master this topic.
Learn Astro API endpoints: create server-side routes that return JSON, handle POST requests, manage form submissions, and build RESTful APIs in your Astro project.
In this lesson, you'll create API endpoints in src/pages/ that return JSON responses, handle request methods, parse form data, and integrate with databases or external services.
What You'll Learn
How to create API endpoints, handle GET, POST, PUT, DELETE methods, parse request bodies, set response headers, and manage CORS.
Why It Matters
API endpoints let your Astro site handle dynamic operations like form submissions, user authentication, and data queries without a separate backend server.
Real-World Use
DodaTech's tutorial platform uses Astro API endpoints for newsletter signups, search queries, and user progress tracking.
flowchart LR
A[Client Request] --> B["src/pages/api/"]
B --> C[GET: Fetch Data]
B --> D[POST: Submit Form]
B --> E[DELETE: Remove Item]
C --> F[JSON Response]
style B fill:#ff5a03,color:#fff
Basic API Endpoint
Create src/pages/api/hello.ts:
export async function GET({ request }) {
return new Response(
JSON.stringify({ message: "Hello from Astro API!" }),
{
status: 200,
headers: { "Content-Type": "application/json" },
}
);
}
Output: A GET request to /api/hello returns {"message":"Hello from Astro API!"}.
Handling Multiple Methods
// src/pages/api/contact.ts
export async function POST({ request }) {
const body = await request.json();
const { name, email, message } = body;
if (!name || !email) {
return new Response(
JSON.stringify({ error: "Name and email are required" }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}
// Process the form data (save to database, send email, etc.)
return new Response(
JSON.stringify({ success: true }),
{ status: 200, headers: { "Content-Type": "application/json" } }
);
}
Dynamic API Routes
Use bracket parameters in API routes:
// src/pages/api/users/[id].ts
export async function GET({ params }) {
const { id } = params;
const user = { id, name: `User ${id}`, email: `user${id}@example.com` };
return new Response(
JSON.stringify(user),
{ status: 200, headers: { "Content-Type": "application/json" } }
);
}
export async function DELETE({ params }) {
const { id } = params;
// Delete user from database
return new Response(
JSON.stringify({ deleted: id }),
{ status: 200, headers: { "Content-Type": "application/json" } }
);
}
Form Data Handling
Parse multipart/form-data submissions:
export async function POST({ request }) {
const formData = await request.formData();
const name = formData.get("name");
const avatar = formData.get("avatar"); // File object
// Validate and process
if (!name) {
return new Response(
JSON.stringify({ error: "Name is required" }),
{ status: 400, headers: { "Content-Type": "application/json" } }
);
}
return new Response(
JSON.stringify({ success: true, name }),
{ status: 200, headers: { "Content-Type": "application/json" } }
);
}
CORS Headers
Enable cross-origin requests:
export async function GET({ request }) {
const headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
"Access-Control-Allow-Headers": "Content-Type",
};
// Handle preflight
if (request.method === "OPTIONS") {
return new Response(null, { status: 204, headers });
}
return new Response(
JSON.stringify({ data: "Public data" }),
{ status: 200, headers }
);
}
Common Mistakes
- Not returning a Response object: API endpoints must return a
Responseobject. Returningundefinedor a string causes errors. - Forgetting error handling: Uncaught exceptions in API routes return 500 errors. Wrap logic in try/catch blocks.
- Missing CORS headers for client-side fetch: Browser fetch requests from different origins need CORS headers. Add them explicitly.
- Using API endpoints in static mode: API endpoints only work in server or hybrid mode. Static builds have no server runtime.
- Not validating input data: Always validate and sanitize request bodies. Malicious payloads can exploit unvalidated endpoints.
Practice Questions
How do you create an API endpoint in Astro? Answer: Create a
.tsor.jsfile insrc/pages/api/that exports named functions likeGET,POST,DELETE.What must every API endpoint return? Answer: A
Responseobject. Usenew Response(body, { status, headers }).How do you access URL parameters in an API route? Answer: Through the
paramsargument. For[id].ts, accessparams.id.What mode must Astro be in for API endpoints? Answer: Server or hybrid mode. Static mode does not support API endpoints.
Challenge
Build a simple REST API for a todo list: GET /api/todos returns all items, POST /api/todos creates a new item, DELETE /api/todos/[id] removes an item. Use in-memory storage.
Mini Project
Create a newsletter signup API endpoint that accepts email via POST, validates the email format, stores it in a JSON file (or simulates storage), and returns appropriate success or error responses.
FAQ
What's Next
Learn about Astro Middleware for intercepting requests and adding cross-cutting concerns to your SSR app.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro