--- name: server-routes description: API routes, server middleware, and Nitro server engine in Nuxt --- # Server Routes Nuxt includes Nitro server engine for building full-stack applications with API routes and server middleware. ## API Routes Create files in `server/api/` directory: ```ts // server/api/hello.ts export default defineEventHandler((event) => { return { message: 'Hello World' } }) ``` Access at `/api/hello`. ### HTTP Methods ```ts // server/api/users.get.ts - GET /api/users export default defineEventHandler(() => { return getUsers() }) // server/api/users.post.ts - POST /api/users export default defineEventHandler(async (event) => { const body = await readBody(event) return createUser(body) }) // server/api/users/[id].put.ts - PUT /api/users/:id export default defineEventHandler(async (event) => { const id = getRouterParam(event, 'id') const body = await readBody(event) return updateUser(id, body) }) // server/api/users/[id].delete.ts - DELETE /api/users/:id export default defineEventHandler((event) => { const id = getRouterParam(event, 'id') return deleteUser(id) }) ``` ### Route Parameters ```ts // server/api/posts/[id].ts export default defineEventHandler((event) => { const id = getRouterParam(event, 'id') return getPost(id) }) // Catch-all: server/api/[...path].ts export default defineEventHandler((event) => { const path = getRouterParam(event, 'path') return { path } }) ``` ### Query Parameters ```ts // server/api/search.ts // GET /api/search?q=nuxt&page=1 export default defineEventHandler((event) => { const query = getQuery(event) // { q: 'nuxt', page: '1' } return search(query.q, Number(query.page)) }) ``` ### Request Body ```ts // server/api/submit.post.ts export default defineEventHandler(async (event) => { const body = await readBody(event) // Validate and process body return { success: true, data: body } }) ``` ### Headers and Cookies ```ts // server/api/auth.ts export default defineEventHandler((event) => { // Read headers const auth = getHeader(event, 'authorization') // Read cookies const cookies = parseCookies(event) const token = getCookie(event, 'token') // Set headers setHeader(event, 'X-Custom-Header', 'value') // Set cookies setCookie(event, 'token', 'new-token', { httpOnly: true, secure: true, maxAge: 60 * 60 * 24, // 1 day }) return { authenticated: !!token } }) ``` ## Server Middleware Runs on every request before routes: ```ts // server/middleware/auth.ts export default defineEventHandler((event) => { const token = getCookie(event, 'token') // Attach data to event context event.context.user = token ? verifyToken(token) : null }) // server/middleware/log.ts export default defineEventHandler((event) => { console.log(`${event.method} ${event.path}`) }) ``` Access context in routes: ```ts // server/api/profile.ts export default defineEventHandler((event) => { const user = event.context.user if (!user) { throw createError({ statusCode: 401, message: 'Unauthorized' }) } return user }) ``` ## Error Handling ```ts // server/api/users/[id].ts export default defineEventHandler((event) => { const id = getRouterParam(event, 'id') const user = findUser(id) if (!user) { throw createError({ statusCode: 404, statusMessage: 'User not found', }) } return user }) ``` ## Server Utils Auto-imported in `server/utils/`: ```ts // server/utils/db.ts export function useDb() { return createDbConnection() } ``` ```ts // server/api/users.ts export default defineEventHandler(() => { const db = useDb() // Auto-imported return db.query('SELECT * FROM users') }) ``` ## Server Plugins Run once when server starts: ```ts // server/plugins/db.ts export default defineNitroPlugin((nitroApp) => { // Initialize database connection const db = createDbConnection() // Add to context nitroApp.hooks.hook('request', (event) => { event.context.db = db }) }) ``` ## Streaming Responses ```ts // server/api/stream.ts export default defineEventHandler((event) => { setHeader(event, 'Content-Type', 'text/event-stream') setHeader(event, 'Cache-Control', 'no-cache') setHeader(event, 'Connection', 'keep-alive') const stream = new ReadableStream({ async start(controller) { for (let i = 0; i < 10; i++) { controller.enqueue(`data: ${JSON.stringify({ count: i })}\n\n`) await new Promise(r => setTimeout(r, 1000)) } controller.close() }, }) return stream }) ``` ## Server Storage Key-value storage with multiple drivers: ```ts // server/api/cache.ts export default defineEventHandler(async (event) => { const storage = useStorage() // Set value await storage.setItem('key', { data: 'value' }) // Get value const data = await storage.getItem('key') return data }) ``` Configure storage drivers in `nuxt.config.ts`: ```ts export default defineNuxtConfig({ nitro: { storage: { redis: { driver: 'redis', url: 'redis://localhost:6379', }, }, }, }) ```