Build API endpoints in the server directory with defineEventHandler — return JSON, read the body and query, and handle params.
Why: any file under server/api becomes an API endpoint. Export defineEventHandler and return a value — Nuxt turns it into JSON automatically. Note: the file path is the URL, so server/api/posts.ts is /api/posts.
// server/api/posts.ts -> GET /api/posts
export default defineEventHandler(() => {
return [
{ id: 1, title: 'Hello' },
{ id: 2, title: 'World' },
]
})Why: values after the ? in the URL come from getQuery(event). Use them for search, filtering, or pagination. Note: the event object holds everything about the incoming request.
// server/api/search.ts -> /api/search?q=nuxt
export default defineEventHandler((event) => {
const { q } = getQuery(event)
return { query: q ?? '' }
})Why: to accept data, read the request body with readBody(event). Name the file with a .post.ts suffix to only respond to POST requests.
// server/api/posts.post.ts -> POST /api/posts
export default defineEventHandler(async (event) => {
const body = await readBody(event)
// ...save body
return { created: body }
})Why: name a file with square brackets and that part of the path becomes a param, read with getRouterParam. Use it to look up one record.
// server/api/posts/[id].ts -> GET /api/posts/123
export default defineEventHandler((event) => {
const id = getRouterParam(event, 'id')
return { id }
})