Back to catalog

api-endpoint-builder

This skill builds REST and GraphQL API endpoints with validation, error handling, and documentation. Supports Python (FastAPI, Flask), Node.js (Express, Fastify, Hono), Bun, and Go (Gin, Echo). Generates request/response validation (Pydantic, Zod), OpenAPI docs, error responses, and tests. Activate when user says "create API endpoint", "add REST route", "build GraphQL resolver", or needs CRUD operations.

  • Category: discovered
  • Tags: github, community
  • Version: 1.0.0
  • Author: walid
  • Downloads: 0
  • Updated: 2025-11-22

Download the latest version (v1.0.0) from this page.

SKILL.md

---
name: api-endpoint-builder
description: |
  This skill builds REST and GraphQL API endpoints with validation, error handling, and documentation.
  Supports Python (FastAPI, Flask), Node.js (Express, Fastify, Hono), Bun, and Go (Gin, Echo).
  Generates request/response validation (Pydantic, Zod), OpenAPI docs, error responses, and tests.
  Activate when user says "create API endpoint", "add REST route", "build GraphQL resolver", or needs CRUD operations.
  Output: Production-ready endpoint code with validation, error handling, tests, and documentation.
---

# API Endpoint Builder

> **Purpose**: Generate production-ready API endpoints with validation, error handling, and documentation

---

## When to Use This Skill

Activate when:
- ✅ User wants to create REST API endpoints (GET, POST, PUT, DELETE)
- ✅ User needs GraphQL resolvers/mutations
- ✅ Building CRUD operations for a resource
- ✅ Adding new routes to existing API
- ✅ Need request/response validation
- ✅ Requests like: "create user endpoint", "add product API", "build order routes"

---

## What This Skill Does

**Generates complete API endpoints with**:
1. **Route handler** - HTTP method, path, parameters
2. **Request validation** - Body, query params, headers (Pydantic/Zod)
3. **Response schema** - Typed responses with status codes
4. **Error handling** - Standardized error responses (400, 404, 500)
5. **Database integration** - ORM queries (Prisma, SQLAlchemy)
6. **Authentication** - JWT/session checks if needed
7. **Documentation** - OpenAPI/Swagger annotations
8. **Tests** - Unit tests for endpoint logic

---

## Supported Technologies

### Python
- **FastAPI** (recommended) - Async, Pydantic validation, auto OpenAPI
- **Flask** - Lightweight, Flask-RESTful extension
- **Django REST Framework** - Full-featured with serializers

### Node.js / Bun
- **Hono** (recommended for Bun) - Fast, TypeScript-first
- **Express** - Classic, middleware-based
- **Fastify** - High performance, schema validation
- **NestJS** - Enterprise, decorator-based

### Go
- **Gin** - Fast HTTP framework
- **Echo** - Minimalist, high performance
- **Fiber** - Express-inspired

---

## Output Format

### REST Endpoint Structure

**FastAPI (Python)**:
```python
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field
from typing import List, Optional
from sqlalchemy.orm import Session
from app.database import get_db
from app.models import User
from app.auth import get_current_user

router = APIRouter(prefix="/users", tags=["users"])

# Request schemas
class UserCreate(BaseModel):
    email: str = Field(..., example="user@example.com")
    password: str = Field(..., min_length=8)
    name: str = Field(..., min_length=2, max_length=100)

class UserResponse(BaseModel):
    id: int
    email: str
    name: str
    created_at: str

    class Config:
        from_attributes = True

# Endpoints
@router.post("/", response_model=UserResponse, status_code=201)
async def create_user(
    user: UserCreate,
    db: Session = Depends(get_db)
):
    """Create a new user with validation"""
    # Check if user exists
    existing = db.query(User).filter(User.email == user.email).first()
    if existing:
        raise HTTPException(status_code=400, detail="Email already registered")

    # Create user
    db_user = User(**user.dict())
    db.add(db_user)
    db.commit()
    db.refresh(db_user)

    return db_user

@router.get("/{user_id}", response_model=UserResponse)
async def get_user(
    user_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """Get user by ID"""
    user = db.query(User).filter(User.id == user_id).first()
    if not user:
        raise HTTPException(status_code=404, detail="User not found")

    return user

@router.get("/", response_model=List[UserResponse])
async def list_users(
    skip: int = 0,
    limit: int = 100,
    db: Session = Depends(get_db)
):
    """List users with pagination"""
    users = db.query(User).offset(skip).limit(limit).all()
    return users

@router.put("/{user_id}", response_model=UserResponse)
async def update_user(
    user_id: int,
    user: UserCreate,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """Update user"""
    db_user = db.query(User).filter(User.id == user_id).first()
    if not db_user:
        raise HTTPException(status_code=404, detail="User not found")

    for key, value in user.dict().items():
        setattr(db_user, key, value)

    db.commit()
    db.refresh(db_user)
    return db_user

@router.delete("/{user_id}", status_code=204)
async def delete_user(
    user_id: int,
    db: Session = Depends(get_db),
    current_user: User = Depends(get_current_user)
):
    """Delete user"""
    db_user = db.query(User).filter(User.id == user_id).first()
    if not db_user:
        raise HTTPException(status_code=404, detail="User not found")

    db.delete(db_user)
    db.commit()
    return None
```

**Hono (Bun/Node)**:
```typescript
import { Hono } from 'hono';
import { z } from 'zod';
import { zValidator } from '@hono/zod-validator';
import { db } from './database';
import { users } from './schema';
import { eq } from 'drizzle-orm';

const app = new Hono();

// Validation schemas
const createUserSchema = z.object({
  email: z.string().email(),
  password: z.string().min(8),
  name: z.string().min(2).max(100)
});

const userResponseSchema = z.object({
  id: z.number(),
  email: z.string(),
  name: z.string(),
  createdAt: z.string()
});

// Endpoints
app.post('/users', zValidator('json', createUserSchema), async (c) => {
  const data = c.req.valid('json');

  // Check if user exists
  const existing = await db.select().from(users).where(eq(users.email, data.email)).get();
  if (existing) {
    return c.json({ error: 'Email already registered' }, 400);
  }

  // Create user
  const user = await db.insert(users).values(data).returning().get();

  return c.json(user, 201);
});

app.get('/users/:id', async (c) => {
  const id = parseInt(c.req.param('id'));

  const user = await db.select().from(users).where(eq(users.id, id)).get();
  if (!user) {
    return c.json({ error: 'User not found' }, 404);
  }

  return c.json(user);
});

app.get('/users', async (c) => {
  const skip = parseInt(c.req.query('skip') || '0');
  const limit = parseInt(c.req.query('limit') || '100');

  const userList = await db.select().from(users).limit(limit).offset(skip).all();

  return c.json(userList);
});

export default app;
```

---

## Best Practices

1. **Validation First**
   - Validate all inputs (body, query, params, headers)
   - Use type-safe schemas (Pydantic, Zod)
   - Return clear validation errors (400 Bad Request)

2. **Error Handling**
   - Use standard HTTP status codes
   - Return consistent error format
   ```json
   {
     "error": "User not found",
     "code": "USER_NOT_FOUND",
     "status": 404
   }
   ```

3. **Security**
   - Authenticate protected endpoints
   - Validate authorization (user owns resource)
   - Sanitize inputs (prevent SQL injection, XSS)
   - Rate limit endpoints

4. **Performance**
   - Use pagination for list endpoints (skip/limit)
   - Optimize database queries (avoid N+1)
   - Add caching for read-heavy endpoints (Redis)

5. **Documentation**
   - Add docstrings/comments
   - Generate OpenAPI/Swagger docs
   - Include request/response examples

---

## Common Patterns

### CRUD Operations
```
POST   /resources        → Create
GET    /resources/:id    → Read one
GET    /resources        → Read list (with pagination)
PUT    /resources/:id    → Update
DELETE /resources/:id    → Delete
```

### Nested Resources
```
GET /users/:userId/posts           → User's posts
POST /users/:userId/posts          → Create post for user
GET /posts/:postId/comments        → Post comments
```

### Filtering & Search
```
GET /products?category=electronics&min_price=100&max_price=500
GET /users?search=john&role=admin&sort=created_at&order=desc
```

### Bulk Operations
```
POST /users/bulk       → Create multiple users
DELETE /users/bulk     → Delete multiple users
```

---

## Tests

**Always generate tests for endpoints**:

```python
# test_users.py
import pytest
from fastapi.testclient import TestClient
from app.main import app

client = TestClient(app)

def test_create_user():
    response = client.post("/users", json={
        "email": "test@example.com",
        "password": "password123",
        "name": "Test User"
    })
    assert response.status_code == 201
    assert response.json()["email"] == "test@example.com"

def test_create_user_duplicate_email():
    # Create first user
    client.post("/users", json={
        "email": "duplicate@example.com",
        "password": "password123",
        "name": "User One"
    })

    # Try to create duplicate
    response = client.post("/users", json={
        "email": "duplicate@example.com",
        "password": "password456",
        "name": "User Two"
    })
    assert response.status_code == 400
    assert "already registered" in response.json()["detail"]

def test_get_user_not_found():
    response = client.get("/users/99999")
    assert response.status_code == 404
```

---

## Integration with Other Skills

- **data-validator-generator** - Creates Pydantic/Zod schemas
- **database-query-optimizer** - Optimizes ORM queries
- **auth-flow-builder** - Adds JWT/OAuth authentication
- **test-suite-generator** - Generates comprehensive tests
- **api-integration-layer** (frontend) - Creates client for these endpoints

---

**Skill Version**: 1.0.0
**Technologies**: Python (FastAPI, Flask), Node/Bun (Hono, Express, Fastify), Go (Gin, Echo)
**Output**: Complete API endpoints with validation, error handling, tests, and docs