|
| 1 | +--- |
| 2 | +name: api-development |
| 3 | +description: Use when creating or modifying Elysia API routes. Ensures proper validation with t schema, auth guards, error handling, and performance patterns. |
| 4 | +allowed-tools: Read, Edit, Write, Glob, Grep, Bash |
| 5 | +--- |
| 6 | + |
| 7 | +API routes use [Elysia](https://elysiajs.com) with TypeBox validation: |
| 8 | + |
| 9 | +```typescript |
| 10 | +import { Elysia, t } from 'elysia' |
| 11 | +import { prisma } from '@/lib/prisma' |
| 12 | + |
| 13 | +const app = new Elysia() |
| 14 | + .get('/tasks/:id', async ({ params, query, status }) => { |
| 15 | + const limit = query.limit ?? 10 |
| 16 | + const task = await prisma.task.findUnique({ |
| 17 | + where: { id: params.id }, |
| 18 | + select: { id: true, title: true } |
| 19 | + }) |
| 20 | + if (!task) return status(404, { error: 'Not found' }) |
| 21 | + return task |
| 22 | + }, { |
| 23 | + params: t.Object({ id: t.String() }), |
| 24 | + query: t.Object({ limit: t.Optional(t.Numeric()) }) |
| 25 | + }) |
| 26 | + .post('/tasks', async ({ body, status }) => { |
| 27 | + const task = await prisma.task.create({ data: body }) |
| 28 | + return status(201, task) |
| 29 | + }, { |
| 30 | + body: t.Object({ |
| 31 | + title: t.String({ minLength: 1 }), |
| 32 | + fullScore: t.Number({ minimum: 0 }) |
| 33 | + }) |
| 34 | + }) |
| 35 | +``` |
| 36 | + |
| 37 | +**Auth guard pattern**: |
| 38 | +```typescript |
| 39 | +.derive(async ({ headers, status }) => { |
| 40 | + const user = await getUser(headers.authorization) |
| 41 | + if (!user) return status(401, { error: 'Unauthorized' }) |
| 42 | + return { user } |
| 43 | +}) |
| 44 | +.get('/admin', ({ user, status }) => { |
| 45 | + if (!user.admin) return status(403, { error: 'Forbidden' }) |
| 46 | + return 'admin only' |
| 47 | +}) |
| 48 | +``` |
| 49 | + |
| 50 | +**Checklist**: `t.Object` validation, auth derive/guard, selective Prisma fields, pagination, `status()` for errors. |
0 commit comments