Claude
Skills
Sign in
Back

Integration Patterns

Included with Lifetime
$97 forever

Expertise in API design, database integration, and service connectivity. Activates when working with "API", "database", "webhook", "service", "integrate", "connect", or system architecture.

Design

What this skill does


# Integration Patterns Skill

## Overview

Design and implement robust integration patterns for connecting services, databases, and external systems. This skill encompasses RESTful and GraphQL API design, database connection management, event-driven architecture, webhook processing, retry strategies, and resilient service communication patterns.

## Core Competencies

### REST API Design

**Design Resource-Oriented APIs:**

Structure REST APIs following best practices with proper HTTP semantics:

```typescript
// src/api/users/users.controller.ts
import { Router, Request, Response, NextFunction } from 'express';
import { UserService } from './user.service';
import { validateRequest } from '../../middleware/validation';
import { authenticate } from '../../middleware/auth';
import { rateLimit } from '../../middleware/rate-limit';
import { CreateUserDto, UpdateUserDto, UserQueryDto } from './user.dto';

export class UsersController {
  public router = Router();

  constructor(private userService: UserService) {
    this.setupRoutes();
  }

  private setupRoutes(): void {
    // List users with pagination and filtering
    this.router.get(
      '/',
      authenticate,
      rateLimit({ windowMs: 60000, max: 100 }),
      validateRequest(UserQueryDto, 'query'),
      this.listUsers.bind(this)
    );

    // Get single user
    this.router.get(
      '/:id',
      authenticate,
      this.getUser.bind(this)
    );

    // Create user
    this.router.post(
      '/',
      rateLimit({ windowMs: 60000, max: 10 }),
      validateRequest(CreateUserDto, 'body'),
      this.createUser.bind(this)
    );

    // Update user (full update)
    this.router.put(
      '/:id',
      authenticate,
      validateRequest(UpdateUserDto, 'body'),
      this.updateUser.bind(this)
    );

    // Partial update
    this.router.patch(
      '/:id',
      authenticate,
      validateRequest(UpdateUserDto, 'body', { partial: true }),
      this.patchUser.bind(this)
    );

    // Delete user
    this.router.delete(
      '/:id',
      authenticate,
      this.deleteUser.bind(this)
    );
  }

  private async listUsers(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const { page = 1, limit = 20, sort = 'createdAt', order = 'desc', search } = req.query;

      const result = await this.userService.findAll({
        page: Number(page),
        limit: Number(limit),
        sort: sort as string,
        order: order as 'asc' | 'desc',
        search: search as string,
      });

      res.status(200).json({
        data: result.users,
        pagination: {
          page: result.page,
          limit: result.limit,
          total: result.total,
          pages: Math.ceil(result.total / result.limit),
        },
        links: {
          self: `/api/users?page=${result.page}&limit=${result.limit}`,
          next: result.page < Math.ceil(result.total / result.limit)
            ? `/api/users?page=${result.page + 1}&limit=${result.limit}`
            : null,
          prev: result.page > 1
            ? `/api/users?page=${result.page - 1}&limit=${result.limit}`
            : null,
        },
      });
    } catch (error) {
      next(error);
    }
  }

  private async getUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const user = await this.userService.findById(req.params.id);

      if (!user) {
        res.status(404).json({
          error: 'Not Found',
          message: 'User not found',
          statusCode: 404,
        });
        return;
      }

      res.status(200).json({
        data: user,
        links: {
          self: `/api/users/${user.id}`,
          posts: `/api/users/${user.id}/posts`,
          comments: `/api/users/${user.id}/comments`,
        },
      });
    } catch (error) {
      next(error);
    }
  }

  private async createUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const user = await this.userService.create(req.body);

      res.status(201)
        .location(`/api/users/${user.id}`)
        .json({
          data: user,
          links: {
            self: `/api/users/${user.id}`,
          },
        });
    } catch (error) {
      next(error);
    }
  }

  private async updateUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const user = await this.userService.update(req.params.id, req.body);

      if (!user) {
        res.status(404).json({
          error: 'Not Found',
          message: 'User not found',
          statusCode: 404,
        });
        return;
      }

      res.status(200).json({
        data: user,
      });
    } catch (error) {
      next(error);
    }
  }

  private async patchUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const user = await this.userService.patch(req.params.id, req.body);

      if (!user) {
        res.status(404).json({
          error: 'Not Found',
          message: 'User not found',
          statusCode: 404,
        });
        return;
      }

      res.status(200).json({
        data: user,
      });
    } catch (error) {
      next(error);
    }
  }

  private async deleteUser(req: Request, res: Response, next: NextFunction): Promise<void> {
    try {
      const deleted = await this.userService.delete(req.params.id);

      if (!deleted) {
        res.status(404).json({
          error: 'Not Found',
          message: 'User not found',
          statusCode: 404,
        });
        return;
      }

      res.status(204).send();
    } catch (error) {
      next(error);
    }
  }
}
```

**Implement Consistent Error Handling:**

Create standardized error responses across all endpoints:

```typescript
// src/middleware/error-handler.ts
import { Request, Response, NextFunction } from 'express';

export class AppError extends Error {
  constructor(
    public statusCode: number,
    public message: string,
    public isOperational = true,
    public errors?: Record<string, string[]>
  ) {
    super(message);
    Object.setPrototypeOf(this, AppError.prototype);
  }
}

export function errorHandler(
  err: Error | AppError,
  req: Request,
  res: Response,
  next: NextFunction
): void {
  if (err instanceof AppError) {
    res.status(err.statusCode).json({
      error: err.message,
      statusCode: err.statusCode,
      errors: err.errors,
      path: req.path,
      method: req.method,
      timestamp: new Date().toISOString(),
    });
    return;
  }

  // Unhandled errors
  console.error('Unhandled error:', err);
  res.status(500).json({
    error: 'Internal Server Error',
    statusCode: 500,
    message: process.env.NODE_ENV === 'development' ? err.message : 'An unexpected error occurred',
    path: req.path,
    method: req.method,
    timestamp: new Date().toISOString(),
  });
}
```

### GraphQL API Design

**Design Type-Safe GraphQL Schema:**

Implement GraphQL APIs with proper type definitions and resolvers:

```typescript
// src/graphql/schema.ts
import { gql } from 'apollo-server-express';

export const typeDefs = gql`
  type User {
    id: ID!
    name: String!
    email: String!
    posts: [Post!]!
    createdAt: DateTime!
    updatedAt: DateTime!
  }

  type Post {
    id: ID!
    title: String!
    content: String!
    author: User!
    comments: [Comment!]!
    published: Boolean!
    createdAt: DateTime!
    updatedAt: DateTime!
  }

  type Comment {
    id: ID!
    content: String!
    author: User!
    post: Post!
    createdAt: DateTime!
  }

  type Query {
    user(id: ID!): User
    users(
      page: Int = 1
      limit: Int = 20
      search: String
    ): UserConnection!

    post(id: ID!): Post
    posts(
      page: Int = 1
      limit: Int = 20
      published: Boolean
    ): PostConnection!
  }

  type Mutation {
    createUser(input: CreateUserInput!): User!
    updateUser(id: ID!, input: UpdateUserInput!): User!
    deleteUser(id: ID!): Boolean!

    createPost(input: CreatePostInp

Related in Design