Back to list
dcyfr

dcyfr-api-patterns

by dcyfr

DCYFR Labs

2🍴 0📅 Jan 25, 2026

SKILL.md


name: dcyfr-api-patterns description: Guide API routes with Validate→Queue→Respond pattern and Inngest integration license: MIT compatibility: opencode metadata: audience: developers workflow: api-implementation category: backend

What I do

I ensure DCYFR API routes follow the Validate → Queue → Respond pattern with Inngest integration:

  • Validate - Input validation and error handling
  • Queue - Offload processing to Inngest background jobs
  • Respond - Immediate user feedback (non-blocking)
  • Error handling - Consistent error responses
  • Rate limiting - Protect against abuse

When to use me

Use this skill when:

  • Creating new API routes
  • Integrating Inngest background jobs
  • Implementing form submissions or webhooks
  • Setting up async processing workflows

Don't use this skill for:

  • Server-side data fetching (use Next.js data fetching patterns)
  • Client-side API calls (use SWR or React Query)
  • Real-time features (use WebSockets/Server-Sent Events)

Core Pattern: Validate → Queue → Respond

Standard API Route

// src/app/api/submit/route.ts
import { NextRequest, NextResponse } from 'next/server';
import { inngest } from '@/lib/inngest';

export async function POST(request: NextRequest) {
  // STEP 1: VALIDATE
  const data = await request.json();
  
  if (!data.email || !data.message) {
    return NextResponse.json(
      { error: 'Missing required fields' },
      { status: 400 }
    );
  }

  // STEP 2: QUEUE
  await inngest.send({
    name: 'form/submission',
    data: {
      email: data.email,
      message: data.message,
      timestamp: new Date().toISOString(),
    },
  });

  // STEP 3: RESPOND
  return NextResponse.json(
    { success: true, message: 'Submission received' },
    { status: 202 } // 202 Accepted - processing async
  );
}

Inngest Event Naming

Convention: domain/action

Examples:

  • form/submission - Form submitted
  • post/published - Blog post published
  • user/signup - User created
  • analytics/track - Analytics event

Error Handling

Standard Error Responses

// 400 Bad Request - Validation failure
return NextResponse.json(
  { error: 'Invalid input', details: validationErrors },
  { status: 400 }
);

// 401 Unauthorized - Missing auth
return NextResponse.json(
  { error: 'Unauthorized' },
  { status: 401 }
);

// 429 Too Many Requests - Rate limit
return NextResponse.json(
  { error: 'Rate limit exceeded', retryAfter: 60 },
  { status: 429 }
);

// 500 Internal Server Error - Unexpected failure
return NextResponse.json(
  { error: 'Internal server error' },
  { status: 500 }
);

Rate Limiting

import { rateLimit } from '@/lib/rate-limit';

export async function POST(request: NextRequest) {
  // Check rate limit
  const ip = request.headers.get('x-forwarded-for') || 'unknown';
  const rateLimitResult = await rateLimit(ip, {
    limit: 5,
    window: 60, // 5 requests per minute
  });

  if (!rateLimitResult.success) {
    return NextResponse.json(
      { error: 'Rate limit exceeded' },
      { status: 429 }
    );
  }

  // Continue processing...
}

Common Patterns

Form Submission

export async function POST(request: NextRequest) {
  const data = await request.json();
  
  // Validate
  if (!data.email || !data.message) {
    return NextResponse.json({ error: 'Missing fields' }, { status: 400 });
  }

  // Queue
  await inngest.send({
    name: 'form/submission',
    data: { email: data.email, message: data.message },
  });

  // Respond
  return NextResponse.json({ success: true }, { status: 202 });
}

Webhook Handler

export async function POST(request: NextRequest) {
  const signature = request.headers.get('x-webhook-signature');
  
  // Validate signature
  if (!verifyWebhookSignature(signature)) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
  }

  const payload = await request.json();

  // Queue
  await inngest.send({
    name: 'webhook/received',
    data: payload,
  });

  // Respond
  return NextResponse.json({ received: true }, { status: 200 });
}

Validation

# Check API patterns
npm run lint

# Test API routes
npm run test:run src/app/api/

# Full quality check
npm run check
  • Full API patterns: .github/agents/patterns/API_PATTERNS.md
  • Inngest documentation: docs/features/inngest-integration.md
  • Rate limiting: src/lib/rate-limit.ts

Approval Gates

API pattern compliance is FLEXIBLE (warning only):

  • ⚠️ Reviewed during PR
  • ⚠️ 80% of POST routes should use Inngest
  • ✅ Must have validation and error handling

Score

Total Score

65/100

Based on repository quality metrics

SKILL.md

SKILL.mdファイルが含まれている

+20
LICENSE

ライセンスが設定されている

+10
説明文

100文字以上の説明がある

0/10
人気

GitHub Stars 100以上

0/15
最近の活動

1ヶ月以内に更新

+10
フォーク

10回以上フォークされている

0/5
Issue管理

オープンIssueが50未満

+5
言語

プログラミング言語が設定されている

+5
タグ

1つ以上のタグが設定されている

+5

Reviews

💬

Reviews coming soon