| name | api-review |
| description | Review API endpoints, routes, and request handlers for security, performance, error handling, and best practices. Use when reviewing API code, creating new endpoints, checking authentication, or auditing API security. Covers Next.js API routes and Supabase integration. |
| allowed-tools | Read, Grep, Glob |
API Review
Comprehensive review of API endpoints and request handlers.
Instructions
Review Checklist
When reviewing API code, systematically check:
- Authentication & Authorization
- Input Validation
- Error Handling
- Security
- Performance
- Response Format
- Documentation
1. Authentication & Authorization
Check for:
- Authentication verification at start of handler
- Proper session/token validation
- Authorization checks (user permissions)
- Protected routes implementation
Good Patterns:
export async function POST(request: Request) {
const supabase = createServerClient()
const { data: { user }, error } = await supabase.auth.getUser()
if (error || !user) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
if (!hasPermission(user, 'resource:write')) {
return NextResponse.json({ error: 'Forbidden' }, { status: 403 })
}
}
Red Flags:
- Missing authentication checks
- Hardcoded credentials
- Admin endpoints without proper guards
- Client-side only security
2. Input Validation
Check for:
- All inputs validated before use
- Type checking and sanitization
- Schema validation (Zod, Yup, etc.)
- SQL injection protection
- XSS prevention
Good Patterns:
import { z } from 'zod'
const schema = z.object({
email: z.string().email(),
age: z.number().min(0).max(120),
name: z.string().min(1).max(100)
})
export async function POST(request: Request) {
const body = await request.json()
const result = schema.safeParse(body)
if (!result.success) {
return NextResponse.json(
{ error: 'Invalid input', details: result.error },
{ status: 400 }
)
}
const { email, age, name } = result.data
}
Red Flags:
- Direct use of user input without validation
- Type coercion without checking
- Missing length/range checks
- No sanitization of HTML/SQL
3. Error Handling
Check for:
- Try-catch blocks around risky operations
- Proper error messages (no stack traces to client)
- Appropriate HTTP status codes
- Error logging for debugging
Good Patterns:
export async function GET(request: Request) {
try {
const data = await fetchData()
return NextResponse.json(data)
} catch (error) {
console.error('API Error:', error)
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
)
}
}
Red Flags:
- Unhandled promise rejections
- Exposing stack traces to client
- Generic error messages without logging
- Wrong HTTP status codes
4. Security
Check for:
- CORS configuration
- Rate limiting
- SQL injection prevention (use parameterized queries)
- XSS protection
- CSRF tokens where needed
- Sensitive data in logs
Good Patterns:
const { data, error } = await supabase
.from('users')
.select('*')
.eq('id', userId)
export const config = {
runtime: 'edge',
maxDuration: 5
}
const headers = {
'Access-Control-Allow-Origin': process.env.ALLOWED_ORIGIN,
'Access-Control-Allow-Methods': 'GET, POST',
'Access-Control-Allow-Headers': 'Content-Type, Authorization'
}
Red Flags:
- String concatenation in SQL queries
- Credentials in code or logs
- Missing rate limiting on public endpoints
- Wide-open CORS (
*)
- Sensitive data in response without need
5. Performance
Check for:
- Efficient database queries
- Proper indexing usage
- Caching where appropriate
- Pagination for large datasets
- N+1 query problems
Good Patterns:
const limit = 20
const offset = page * limit
const { data } = await supabase
.from('posts')
.select('*')
.range(offset, offset + limit - 1)
const { data } = await supabase
.from('users')
.select('id, name, email')
const { data } = await supabase
.from('posts')
.select('*')
.eq('user_id', userId)
Red Flags:
- SELECT * on large tables
- No pagination
- Queries in loops (N+1)
- Missing database indexes
- Synchronous operations blocking
6. Response Format
Check for:
- Consistent response structure
- Appropriate status codes
- Proper content-type headers
- No sensitive data leakage
Good Patterns:
return NextResponse.json({
data: result,
meta: { page, total }
}, { status: 200 })
return NextResponse.json({
error: 'Resource not found',
code: 'NOT_FOUND'
}, { status: 404 })
200 - OK
201 - Created
400 - Bad Request
401 - Unauthorized
403 - Forbidden
404 - Not Found
500 - Internal Server Error
Red Flags:
- Inconsistent response format
- Always returning 200
- Exposing internal IDs
- Missing pagination metadata
7. Documentation
Check for:
- JSDoc comments on handlers
- API documentation (OpenAPI/Swagger)
- Request/response examples
- Required permissions noted
Good Patterns:
export async function POST(request: Request) {
}
Review Process
-
Read the endpoint code
- Use Read tool to examine handler
- Note dependencies and imports
-
Check against checklist
- Go through each security/quality item
- Flag issues with severity (Critical/High/Medium/Low)
-
Suggest improvements
- Provide specific code examples
- Explain why change is needed
- Consider backward compatibility
-
Verify tests exist
- Check for unit/integration tests
- Suggest test cases if missing
Common Issues by Framework
Next.js API Routes
Check:
- Using
NextResponse for responses
- Proper route file naming (route.ts)
- Edge runtime for performance-critical routes
- Middleware for common logic
Supabase Integration
Check:
- Using server client (not anon client)
- RLS policies enabled on tables
- Proper auth context passed
- Connection pooling configured
Examples
User asks: "Review this API endpoint"
I will:
- Read the endpoint code
- Check all 7 review categories
- Identify security issues (priority)
- Note performance concerns
- Suggest specific improvements with code examples
- Flag missing tests
- Provide severity ratings for issues
User asks: "Is this endpoint secure?"
I will:
- Focus on security checklist items
- Check auth/authorization
- Review input validation
- Look for injection vulnerabilities
- Verify error handling doesn't leak info
- Check for common OWASP issues
- Provide actionable security recommendations
Red Flag Keywords
When scanning code, watch for:
eval()
- String concatenation in SQL
dangerouslySetInnerHTML
- Hardcoded secrets/keys
SELECT *
- Missing
try-catch
any types everywhere
- No input validation
- CORS:
*
- Admin checks on client side only