Unnamed Skill

Service 层架构与前后端联调规范。Use when creating API services, writing Service classes, or handling backend integration. Triggers on: creating services, API calls, BaseService pattern, rewrites configuration, error handling.

$ 安裝

git clone https://github.com/SammySnake-d/ai-frontend-scaffold /tmp/ai-frontend-scaffold && cp -r /tmp/ai-frontend-scaffold/.agent/skills/service-layer ~/.claude/skills/ai-frontend-scaffold

// tip: Run this command in your terminal to install the skill


name: service-layer description: Service 层架构与前后端联调规范。Use when creating API services, writing Service classes, or handling backend integration. Triggers on: creating services, API calls, BaseService pattern, rewrites configuration, error handling.

Service Layer Guide

Service 层架构与前后端联调规范。

Directory Structure

lib/services/
├── core/
│   ├── api-client.ts
│   ├── base.service.ts
│   └── errors.ts
├── auth/
│   ├── auth.service.ts
│   └── types.ts
├── user/
│   ├── user.service.ts
│   └── types.ts
└── index.ts

Service Pattern

export class UserService extends BaseService {
  protected static readonly basePath = '/api/v1/users';

  static async list(): Promise<User[]> {
    return this.get<User[]>('/');
  }

  static async getById({ id }: { id: string }): Promise<User> {
    return this.get<User>(`/${id}`);
  }

  static async create(request: CreateUserRequest): Promise<User> {
    return this.post<User>('/', request);
  }
}

Usage

// ✅ Through services
import services from '@/lib/services';
const users = await services.user.list();

// ❌ Direct axios/fetch
await axios.get('http://localhost:8000/api/users');

Rewrites Configuration

// next.config.ts
async rewrites() {
  return [{
    source: '/api/:path*',
    destination: `${process.env.BACKEND_URL}/api/:path*`,
  }];
}

Error Types

ApiErrorBase
├── NetworkError      // Network issues
├── UnauthorizedError // 401
├── ForbiddenError    // 403
├── NotFoundError     // 404
├── ValidationError   // 400
└── ServerError       // 5xx

Error Handling

try {
  const user = await services.user.getById({ id });
} catch (error) {
  if (error instanceof NotFoundError) {
    toast.error('User not found');
  }
}