Claude Code Plugins

Community-maintained marketplace

Feedback

angular-api-service

@duc01226/EasyPlatform
2
0

Use when creating API services for backend communication with proper patterns for caching, error handling, and type safety.

Install Skill

1Download skill
2Enable skills in Claude

Open claude.ai/settings/capabilities and find the "Skills" section

3Upload to Claude

Click "Upload skill" and select the downloaded ZIP file

Note: Please verify skill by going through its instructions before using it.

SKILL.md

name angular-api-service
description Use when creating API services for backend communication with proper patterns for caching, error handling, and type safety.

Angular API Service Development

Required Reading

For comprehensive TypeScript/Angular patterns, you MUST read:

  • docs/claude/frontend-typescript-complete-guide.md - Complete patterns for API services, HTTP patterns, error handling

🎨 Design System Documentation (MANDATORY)

Before creating any API service, read the design system documentation for your target application:

Application Design System Location
PlatformExampleAppWeb docs/design-system/

Key docs to read:

  • README.md - Component overview, base classes, library summary
  • 07-technical-guide.md - Implementation checklist, best practices
  • 06-state-management.md - State management and API integration patterns

API Service Pattern

@Injectable({ providedIn: 'root' })
export class EmployeeApiService extends PlatformApiService {
    protected get apiUrl(): string {
        return environment.apiUrl + '/api/Employee';
    }

    // GET list
    getEmployees(query?: GetEmployeeListQuery): Observable<PagedResult<EmployeeDto>> {
        return this.get<PagedResult<EmployeeDto>>('', query);
    }

    // GET single
    getEmployee(id: string): Observable<EmployeeDto> {
        return this.get<EmployeeDto>(`/${id}`);
    }

    // POST command
    saveEmployee(command: SaveEmployeeCommand): Observable<SaveEmployeeCommandResult> {
        return this.post<SaveEmployeeCommandResult>('', command);
    }

    // POST with caching
    searchEmployees(criteria: SearchCriteria): Observable<EmployeeDto[]> {
        return this.post<EmployeeDto[]>('/search', criteria, {
            enableCache: true
        });
    }

    // DELETE
    deleteEmployee(id: string): Observable<void> {
        return this.delete(`/${id}`);
    }

    // File upload
    uploadDocument(id: string, file: File): Observable<DocumentDto> {
        const formData = new FormData();
        formData.append('file', file);
        return this.post<DocumentDto>(`/${id}/documents`, formData);
    }
}

Service Location

src/PlatformExampleAppWeb/libs/apps-domains/src/lib/
└── text-snippet/
    ├── text-snippet-api.service.ts
    ├── text-snippet.model.ts
    └── text-snippet.validators.ts

Usage in Component/Store

// In store
public loadEmployees = this.effectSimple(
  (query: GetEmployeeListQuery) => this.employeeApi.getEmployees(query).pipe(
    this.tapResponse(result => this.updateState({
      employees: result.items,
      totalCount: result.totalCount
    }))
  ),
  'loadEmployees'
);

// In component
this.employeeApi.saveEmployee(command)
  .pipe(
    this.observerLoadingErrorState('save'),
    this.tapResponse(
      result => this.router.navigate(['/employees', result.id]),
      error => this.showError(error)
    ),
    this.untilDestroyed()
  )
  .subscribe();

Key APIs

Method Purpose
get<T>(path, params?) HTTP GET request
post<T>(path, body, opts?) HTTP POST request
put<T>(path, body) HTTP PUT request
delete(path) HTTP DELETE request

Request/Response Types

// Query DTO (matches backend)
export interface GetEmployeeListQuery {
    skipCount?: number;
    maxResultCount?: number;
    searchText?: string;
    statuses?: EmployeeStatus[];
}

// Command DTO
export interface SaveEmployeeCommand {
    id?: string;
    firstName: string;
    lastName: string;
    email: string;
}

// Paged result
export interface PagedResult<T> {
    items: T[];
    totalCount: number;
}

Anti-Patterns

  • Using HttpClient directly instead of PlatformApiService
  • Hardcoding API URLs (use apiUrl property)
  • Not using type parameters for responses
  • Manual error handling (use tapResponse)