Skip to content
Back to skills

Backend Api Patterns

ASecurity

Backend API implementation patterns for scalability, security, and maintainability. Use when building APIs, services, and backend systems.

  • 666 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 2, 2026
developmenttypescriptgoapidatabasebackendsecurityperformance

Works with

  • api

Security analysis

A100/100

Scanned September 2, 2026

npx -y skills add majiayu000/claude-skill-registry --skill backend-api-patterns --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Backend Api Patterns?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Backend Api Patterns
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/majiayu000-backend-api-patterns-claude-skill-registry/badge)](https://www.skillsdirectory.com/skills/majiayu000-backend-api-patterns-claude-skill-registry)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: backend-api-patterns
description: Backend API implementation patterns for scalability, security, and maintainability. Use when building APIs, services, and backend systems.
---

# Backend API Patterns

Implementation patterns for scalable, secure, and maintainable backend systems.

## When to Use

- Building new API endpoints
- Implementing service layer logic
- Database operations and queries
- Authentication and authorization

## Service Layer Patterns

### Repository Pattern

```typescript
// Separate data access from business logic
interface UserRepository {
  findById(id: string): Promise<User | null>
  findByEmail(email: string): Promise<User | null>
  create(data: CreateUserDto): Promise<User>
  update(id: string, data: UpdateUserDto): Promise<User>
  delete(id: string): Promise<void>
}

class UserService {
  constructor(private readonly userRepo: UserRepository) {}
  
  async createUser(dto: CreateUserDto): Promise<User> {
    // Business logic here
    const existing = await this.userRepo.findByEmail(dto.email)
    if (existing) throw new ConflictError('Email already exists')
    return this.userRepo.create(dto)
  }
}
```

### Unit of Work Pattern

```typescript
// Manage transactions across repositories
interface UnitOfWork {
  users: UserRepository
  orders: OrderRepository
  commit(): Promise<void>
  rollback(): Promise<void>
}

async function createOrderWithUser(uow: UnitOfWork, data: OrderData) {
  try {
    const user = await uow.users.create(data.user)
    const order = await uow.orders.create({ ...data.order, userId: user.id })
    await uow.commit()
    return { user, order }
  } catch (error) {
    await uow.rollback()
    throw error
  }
}
```

## Error Handling

### Custom Error Classes

```typescript
abstract class AppError extends Error {
  abstract statusCode: number
  abstract code: string
}

class NotFoundError extends AppError {
  statusCode = 404
  code = 'NOT_FOUND'
  constructor(resource: string, id: string) {
    super(`${resource} with id ${id} not found`)
  }
}

class ValidationError extends AppError {
  statusCode = 422
  code = 'VALIDATION_ERROR'
  constructor(public errors: FieldError[]) {
    super('Validation failed')
  }
}
```

### Global Error Handler

```typescript
function errorHandler(error: Error, req: Request, res: Response, next: Next) {
  if (error instanceof AppError) {
    return res.status(error.statusCode).json({
      error: {
        code: error.code,
        message: error.message,
        details: error instanceof ValidationError ? error.errors : undefined
      }
    })
  }
  
  // Log unexpected errors
  logger.error('Unexpected error', { error, requestId: req.id })
  
  return res.status(500).json({
    error: { code: 'INTERNAL_ERROR', message: 'An unexpected error occurred' }
  })
}
```

## Database Patterns

### Query Optimization

```typescript
// ❌ N+1 Query Problem
const users = await db.users.findMany()
for (const user of users) {
  user.orders = await db.orders.findMany({ where: { userId: user.id } })
}

// ✅ Eager Loading
const users = await db.users.findMany({
  include: { orders: true }
})

// ✅ Or batch loading
const users = await db.users.findMany()
const orders = await db.orders.findMany({
  where: { userId: { in: users.map(u => u.id) } }
})
```

### Connection Pooling

```typescript
const pool = {
  min: 2,
  max: 10,
  idleTimeoutMs: 30000,
  acquireTimeoutMs: 30000
}
```

## Security Patterns

### Input Validation

```typescript
// Always validate at the boundary
const CreateUserSchema = z.object({
  email: z.string().email(),
  name: z.string().min(2).max(100),
  password: z.string().min(8).regex(/[A-Z]/).regex(/[0-9]/)
})

async function createUser(req: Request) {
  const validated = CreateUserSchema.parse(req.body)
  // Safe to use validated data
}
```

### Authorization

```typescript
// Resource-level authorization
async function getOrder(userId: string, orderId: string) {
  const order = await orderRepo.findById(orderId)
  if (!order) throw new NotFoundError('Order', orderId)
  if (order.userId !== userId) throw new ForbiddenError()
  return order
}
```

## Performance Patterns

### Caching Strategy

```typescript
async function getUserById(id: string): Promise<User> {
  // Check cache first
  const cached = await cache.get(`user:${id}`)
  if (cached) return JSON.parse(cached)
  
  // Fetch from database
  const user = await userRepo.findById(id)
  if (!user) throw new NotFoundError('User', id)
  
  // Store in cache with TTL
  await cache.set(`user:${id}`, JSON.stringify(user), 'EX', 3600)
  return user
}
```

### Rate Limiting

```typescript
const rateLimiter = rateLimit({
  windowMs: 15 * 60 * 1000, // 15 minutes
  max: 100, // limit each IP to 100 requests per window
  message: { error: { code: 'RATE_LIMITED', message: 'Too many requests' } }
})
```

## Logging Standards

```typescript
// Structured logging
logger.info('User created', {
  userId: user.id,
  email: user.email,
  requestId: req.id,
  duration: Date.now() - startTime
})

// Log levels
logger.debug() // Development details
logger.info()  // Business events
logger.warn()  // Potential issues
logger.error() // Errors needing attention
```

## Checklist

Before completing backend implementation:

- [ ] Input validated with schema
- [ ] Errors properly categorized
- [ ] Database queries optimized (no N+1)
- [ ] Authorization checks in place
- [ ] Sensitive data not logged
- [ ] Transaction boundaries defined
- [ ] Caching strategy considered
- [ ] Rate limiting configured

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.