API Routes
Overview
API Routes (app/api/**/route.ts) are used for:
- External service integration (Directus, Redis)
- Proxy endpoints (keeping credentials server-side)
- Special operations (invitations, webhooks)
Implementation Pattern
// app/api/essearch/route.ts
import { NextRequest, NextResponse } from "next/server";
import { createDirectus, rest, authentication } from "@directus/sdk";
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { firstName, lastName, ... } = body.params;
// Authenticate with Directus
const client = createDirectus(directusUrl)
.with(authentication("json"))
.with(rest());
await client.login(email, password);
const token = await client.getToken();
// Call external service
const response = await fetch(`${directusUrl}/essearch/validation`, {
method: "POST",
headers: {
Authorization: `Bearer ${token}`,
},
body: JSON.stringify({ firstName, lastName, ... }),
});
const data = await response.json();
return NextResponse.json({
persons: data.hits || [],
totalHits: data.total?.value,
});
} catch (error) {
return NextResponse.json(
{ error: error.message },
{ status: 500 }
);
}
}
API Route Categories
1. Voter Search APIs
/api/essearch - Dynamic credentials
- Accepts credentials in request body
- Uses environment variables based on
emailKey,passwordKey,endpointKey - Token caching in HTTP-only cookies
/api/essearch-common - Fixed credentials
- Uses
DIRECTUS_API_EMAIL_SEARCH,DIRECTUS_API_PASSWORD_SEARCH,DIRECTUS_URL_SEARCH - Simpler for common search operations
2. Duplicate Detection API
/api/duplicate
// app/api/duplicate/route.ts
export async function POST(req: NextRequest) {
const { campaignId, voterId } = await req.json();
const client = await getRedisConnection();
const exists = await client.sIsMember(
`campaign:${campaignId}:signers`,
voterId
);
return NextResponse.json({ exists: Boolean(exists) });
}
Features:
- Redis set membership check
- Fast duplicate detection
- Connection pooling and error handling
3. Team Invitation API
/api/invite-team-member
- Uses Supabase service role key
- Creates user invitation
- Invokes Supabase Edge Function for email
API Route vs Server Action
| Feature | API Route | Server Action |
|---|---|---|
| URL | /api/endpoint | No URL (direct function call) |
| Use Case | External services, webhooks | Form mutations, CRUD |
| Calling | fetch('/api/endpoint') | Direct function import |
| Type Safety | Manual typing | Full TypeScript support |
| Form Integration | Requires form handling | Direct form action |