09
API Routes
Any file under app/api/ is automatically registered as an API route handler.
HTTP Method Handlers (Case-Insensitive)
Each HTTP method is defined by an exported named function. Method names are case-insensitive (e.g. GET or get, POST or post, PUT or put, DELETE or delete, PATCH or patch, HEAD, OPTIONS).
- Case-Insensitive HTTP Methods: You can export methods in uppercase (GET, POST, PUT, DELETE, PATCH, HEAD, OPTIONS) or lowercase (get, post, put, delete, patch, head, options).
- Default Fallback Handler: If no matching named HTTP method function is exported, export default function(req, res) catches all HTTP requests for that route.
app/api/users/index.ts
import type { Request, Response } from '@nxpress/core';
export const mockUsers = [
{ id: 1, name: 'Alice', email: 'alice@example.com' },
{ id: 2, name: 'Bob', email: 'bob@example.com' }
];
// GET /api/users -> Returns 200 OK + JSON
export async function GET(req: Request, res: Response) {
const search = req.query.search as string;
if (search) {
return mockUsers.filter(u => u.name.toLowerCase().includes(search.toLowerCase()));
}
return mockUsers;
}
// POST /api/users -> Creates record with 201 Created
export async function POST(req: Request, res: Response) {
const { name, email } = req.body;
if (!name || !email) {
res.status(400);
return { error: 'Name and email are required' };
}
const newUser = { id: Date.now(), name, email };
mockUsers.push(newUser);
res.status(201);
return newUser;
}app/api/users/[id].ts
import type { Request, Response } from '@nxpress/core';
import { mockUsers } from '.';
// GET /api/users/:id
export async function GET(req: Request, res: Response) {
const userId = Number(req.params.id);
const user = mockUsers.find(u => u.id === userId);
if (!user) {
res.status(404);
return { error: 'User not found' };
}
return user;
}
// PUT /api/users/:id
export async function PUT(req: Request, res: Response) {
const userId = Number(req.params.id);
const { name, email } = req.body;
const user = mockUsers.find(u => u.id === userId);
if (!user) {
res.status(404);
return { error: 'User not found' };
}
user.name = name ?? user.name;
user.email = email ?? user.email;
return { ...user, updatedAt: new Date().toISOString() };
}
// DELETE /api/users/:id
export async function DELETE(req: Request, res: Response) {
const userId = Number(req.params.id);
const index = mockUsers.findIndex(u => u.id === userId);
if (index !== -1) {
mockUsers.splice(index, 1);
}
return res.status(204).send();
}Automatic Response (Auto-Return)
- Object or Array: Automatically sent via res.json(...).
- String or Buffer: Automatically sent via res.send(...).
- Configured status codes (res.status(...)) are preserved.
- If the handler returns nothing and does not send a response, next() is called automatically.