Skip to main content
ClaudeWave
Skill171 repo starsupdated 1mo ago

API Development

Build REST APIs with proper error handling, status codes, request validation, response formatting, and rate limiting. Apply when creating API routes, handling errors, validating input, or designing API responses.

Install in Claude Code
Copy
git clone --depth 1 https://github.com/ThamJiaHe/claude-code-handbook /tmp/api-development && cp -r /tmp/api-development/skills/examples/api-development- ~/.claude/skills/api-development
Then start a new Claude Code session; the skill loads automatically.

api-development-skill.md

# API Development

Systematic REST API development with error handling, validation, and consistent response formats.

## Overview

This Skill enforces:
- HTTP status codes (appropriate, not overused)
- RFC 7807 Problem Details for errors
- Input validation and sanitization
- Consistent response formatting
- Request correlation IDs
- Rate limiting
- Security-first error messages
- Centralized error handling

Apply when building API routes, handling errors, or designing responses.

## HTTP Status Codes

### Status Code Categories

| Range | Purpose | Common Examples |
|-------|---------|-----------------|
| 200-299 | Success | 200 OK, 201 Created, 204 No Content |
| 300-399 | Redirection | 301 Moved Permanently, 302 Found |
| 400-499 | Client Errors | 400 Bad Request, 401 Unauthorized, 404 Not Found |
| 500-599 | Server Errors | 500 Internal Error, 503 Service Unavailable |

### Correct Status Codes

```ts
// ✅ GOOD: Specific status codes
200  // GET: Resource retrieved
201  // POST: Resource created
204  // DELETE: Resource deleted (no content)
400  // Bad Request: Validation failed
401  // Unauthorized: Not authenticated
403  // Forbidden: Authenticated but no permission
404  // Not Found: Resource doesn't exist
409  // Conflict: Duplicate email
422  // Unprocessable Entity: Semantic error
429  // Too Many Requests: Rate limited
500  // Internal Server Error: Server bug

// ❌ BAD: Vague status codes
200  // Success response for everything
500  // Error response for everything
200  // Returned even when validation failed
```

## Error Response Format (RFC 7807)

### Problem Details Structure

```ts
// RFC 7807 Problem Details
type ProblemDetails = {
  type: string;        // URL to error type documentation
  title: string;       // Short error title
  status: number;      // HTTP status code
  detail: string;      // Specific error details
  instance?: string;   // Request ID for tracking
  errors?: Record<string, string[]>;  // Field-level errors
};
```

### Implementation

```ts
// lib/errors.ts
export class ApiError extends Error {
  constructor(
    public status: number,
    public title: string,
    public detail: string,
    public type: string = 'about:blank',
    public errors?: Record<string, string[]>
  ) {
    super(detail);
    this.name = 'ApiError';
  }

  toJSON() {
    return {
      type: this.type,
      title: this.title,
      status: this.status,
      detail: this.detail,
      instance: this.instance,
      ...(this.errors && { errors: this.errors })
    };
  }
}
```

### Error Responses

```ts
// ✅ GOOD: RFC 7807 format
{
  "type": "https://api.example.com/errors/validation-failed",
  "title": "Validation Failed",
  "status": 400,
  "detail": "The request body contains invalid data",
  "instance": "req-12345",
  "errors": {
    "email": ["Invalid email format"],
    "age": ["Must be >= 18"]
  }
}

// ✅ GOOD: Unauthorized (no sensitive details)
{
  "type": "https://api.example.com/errors/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Authentication required",
  "instance": "req-12346"
}

// ❌ BAD: Leaks internal details
{
  "error": "User not found in database",
  "stack": "Error: query failed at line 42..."
}

// ❌ BAD: Not structured
{
  "message": "Something went wrong"
}
```

## Centralized Error Handler

```ts
// middleware/error-handler.ts
import { NextRequest, NextResponse } from 'next/server';
import { ApiError } from '@/lib/errors';

export function errorHandler(error: unknown) {
  const requestId = crypto.randomUUID();

  // Log error (internal, never exposed)
  console.error(`[${requestId}] Error:`, error);

  // ApiError (predictable)
  if (error instanceof ApiError) {
    return NextResponse.json(
      {
        type: error.type,
        title: error.title,
        status: error.status,
        detail: error.detail,
        instance: requestId,
        ...(error.errors && { errors: error.errors })
      },
      { status: error.status }
    );
  }

  // Validation error
  if (error instanceof ZodError) {
    return NextResponse.json(
      {
        type: 'https://api.example.com/errors/validation-failed',
        title: 'Validation Failed',
        status: 400,
        detail: 'The request body contains invalid data',
        instance: requestId,
        errors: error.flatten().fieldErrors
      },
      { status: 400 }
    );
  }

  // Unknown error (generic message)
  return NextResponse.json(
    {
      type: 'https://api.example.com/errors/internal-server-error',
      title: 'Internal Server Error',
      status: 500,
      detail: 'An unexpected error occurred',
      instance: requestId
    },
    { status: 500 }
  );
}
```

### Using Error Handler

```ts
// app/api/users/route.ts
import { errorHandler } from '@/middleware/error-handler';

export async function POST(request: Request) {
  try {
    const body = await request.json();

    // Validate
    const validated = CreateUserSchema.parse(body);

    // Check duplicate
    const existing = await db.user.findUnique({
      where: { email: validated.email }
    });

    if (existing) {
      throw new ApiError(
        409,
        'Conflict',
        'A user with this email already exists',
        'https://api.example.com/errors/duplicate-email'
      );
    }

    // Create
    const user = await db.user.create({ data: validated });

    return new Response(JSON.stringify(user), {
      status: 201,
      headers: { 'Content-Type': 'application/json' }
    });
  } catch (error) {
    return errorHandler(error);
  }
}
```

## Input Validation

### Schema Validation

```ts
import { z } from 'zod';

const CreateUserSchema = z.object({
  email: z.string().email('Invalid email format'),
  name: z.string().min(1, 'Name required').max(255),
  age: z.number().int().min(0).max(150),
  role: z.enum(['admin', 'user', 'guest']).default('user')
});

// Validate request
const validated = CreateUserSchema.parse(body);
```

### Sanitization

```ts
import DOMPurify from 'isomorp
API Security HardeningSkill

Harden REST and GraphQL APIs against common attack vectors. Apply when building API endpoints, implementing authentication, handling file uploads, or exposing APIs to external consumers.

AWS Cloud InfrastructureSkill

Deploy Node.js applications on AWS using EC2, RDS, and managed services with security best practices. Apply when setting up AWS infrastructure, configuring databases, managing security, or optimizing costs.

Build Error ResolverSkill

Rapidly fix build failures, type errors, and lint issues with minimal diffs. Apply when builds fail, TypeScript reports errors, or CI/CD pipelines break. Focuses on getting the build green fast.

Cybersecurity Threat ModelingSkill

STRIDE-based threat modeling for application architecture. Apply when designing new systems, reviewing architecture, or assessing security posture of existing applications.

Docker ContainerizationSkill

Production-ready Docker patterns for multi-stage builds, security hardening, and orchestration. Apply when creating Dockerfiles, docker-compose configs, or deploying containerized applications.

Git WorkflowSkill

Enforces Conventional Commits, PR standards, merge conflict resolution, and branch management. Apply when committing code, opening PRs, resolving conflicts, managing branches, or handling Git operations.

Google Cloud Platform & APIsSkill

Deploy Node.js applications on Google Cloud with Cloud Run, Cloud Firestore, and Google APIs. Implement OAuth2 authentication and manage service accounts. Apply when building serverless applications, integrating Google services, or deploying to GCP.

Incident ResponseSkill

Structured production incident triage, resolution, and post-mortem. Apply when production systems are down, degraded, or behaving unexpectedly. Covers detection, containment, resolution, and learning.