Documentation
API Routes
Create RESTful APIs with flexible middleware support and built-in validation.
Creating API Routes
Create API routes by adding a route.ts file in the app/api directory:
app/api/posts/route.ts
import type { ApiContext } from "@lolyjs/core";
export async function GET(ctx: ApiContext) {
const posts = await getPosts();
return ctx.Response({ posts });
}
export async function POST(ctx: ApiContext) {
const post = await createPost(ctx.req.body);
return ctx.Response({ post }, 201);
}HTTP Methods
Export functions named after HTTP methods to handle different request types:
app/api/posts/route.ts
import type { ApiContext } from "@lolyjs/core";
export async function GET(ctx: ApiContext) {
// Handle GET requests
return ctx.Response({ data: "value" });
}
export async function POST(ctx: ApiContext) {
// Handle POST requests
return ctx.Response({ created: true }, 201);
}
export async function PUT(ctx: ApiContext) {
// Handle PUT requests
return ctx.Response({ updated: true });
}
export async function DELETE(ctx: ApiContext) {
// Handle DELETE requests
return ctx.Response({ deleted: true }, 204);
}
export async function PATCH(ctx: ApiContext) {
// Handle PATCH requests
return ctx.Response({ patched: true });
}Request & Response
Access request data and send responses:
import type { ApiContext } from "@lolyjs/core";
export async function POST(ctx: ApiContext) {
// Access request data
const { body, query, params, headers } = ctx.req;
// Access locals (set by middlewares)
const user = ctx.locals.user;
// Send response
return ctx.Response(
{ message: "Success", data: body },
200,
{ "Custom-Header": "value" }
);
}API Middlewares
Define middlewares that run before your route handlers:
app/api/protected/route.ts
import type { ApiMiddleware, ApiContext } from "@lolyjs/core";
// Global middleware for all methods
export const beforeApi: ApiMiddleware[] = [
async (ctx, next) => {
// Authentication
const user = await verifyUser(ctx.req);
ctx.locals.user = user;
await next();
},
];
// Method-specific middleware
export const beforePOST: ApiMiddleware[] = [
async (ctx, next) => {
// Validation specific to POST
await next();
},
];
export async function GET(ctx: ApiContext) {
const user = ctx.locals.user; // Available from middleware
return ctx.Response({ user });
}Validation
Validate request data using Zod schemas:
import type { ApiContext } from "@lolyjs/core";
import { validate } from "@lolyjs/core";
import { z } from "zod";
const postSchema = z.object({
title: z.string().min(1),
content: z.string().min(1),
published: z.boolean().optional(),
});
export async function POST(ctx: ApiContext) {
try {
const data = validate(postSchema, ctx.req.body);
const post = await createPost(data);
return ctx.Response({ post }, 201);
} catch (error) {
// ValidationError is thrown by validate() function
return ctx.Response({ error: "Validation failed" }, 400);
}
}