home / skills / cacr92 / wereply / api-design

api-design skill

/.trae/skills/api-design

This skill helps you design consistent API interfaces and DTOs with unified ApiResponse, camelCase fields, and validation at command boundaries.

npx playbooks add skill cacr92/wereply --skill api-design

Review the files below or copy the command above to add this skill to your agents.

Files (1)
SKILL.md
1.8 KB
---
name: api-design
description: 当用户要求API/接口/DTO设计、请求响应结构、分页、命名规范或校验规则时使用。
---

# API Design Skill

## 适用范围
- 设计或调整 Tauri 命令接口
- 设计 DTO/响应结构
- 统一命名与校验策略

## 关键规则(Critical Rules)
- 外层响应统一 `ApiResponse<T>`
- DTO 使用 `serde` + `specta::Type`,字段 camelCase 与前端一致
- 校验在命令边界完成,业务层返回 `anyhow::Result` 并补充上下文
- 错误信息面向用户,简洁明确

## 标准响应
```rust
#[derive(serde::Serialize, specta::Type)]
#[specta(inline)]
pub struct ApiResponse<T: specta::Type> {
    pub success: bool,
    pub data: Option<T>,
    pub error: Option<String>,
}
```

## DTO 规范(示例)
```rust
#[derive(Debug, Clone, Serialize, Deserialize, specta::Type)]
#[serde(rename_all = "camelCase")]
pub struct CreateFactoryDto {
    pub factory_code: Code,
    pub factory_name: Name,
    pub description: Description,
    pub address: Option<String>,
    pub contact: Option<String>,
    pub phone: Option<String>,
    pub is_active: Boolean,
}
```

## 命名与契约
- 命令:动词 + 名词(`get`/`create`/`update`/`delete`)
- DTO:`CreateXDto` / `UpdateXDto` / `XDto`
- 前后端字段统一 camelCase,Rust 侧使用 `#[serde(rename_all = "camelCase")]`

## 分页与列表
- 优先复用现有类型:`crate::material::material_service::MaterialsPage` / `MaterialsPaginatedResult`
- 返回列表时保持字段可直接渲染,避免二次拼装

## 校验建议
- 对 `String` 长度、`Option` 必填进行检查
- SQLx 之前完成基本校验,避免 DB 错误直接暴露

## 检查清单
- [ ] 响应使用 `ApiResponse<T>`
- [ ] DTO 实现 `specta::Type` 且字段 camelCase
- [ ] 校验在命令边界完成
- [ ] 命名与既有命令风格一致

Overview

This skill guides API, DTO, and interface design for Tauri commands and backend-to-frontend contracts. It enforces a consistent response envelope, serde-compatible DTOs, naming conventions, pagination patterns, and validation rules to produce predictable, front-end-friendly APIs.

How this skill works

When invoked, the skill inspects API requirements and outputs DTO definitions, request/response shapes, pagination formats, and validation rules following the ApiResponse<T> envelope. It recommends serde and specta::Type annotations, camelCase field names, command naming patterns, and where to perform input validation versus business error handling.

When to use it

  • Designing or refactoring Tauri command interfaces that communicate with the UI
  • Creating or reviewing DTOs for backend-to-frontend serialization
  • Defining standard API responses and error handling for client consumption
  • Specifying pagination and list endpoints for tables or feeds
  • Establishing naming and validation contracts shared by frontend and backend

Best practices

  • Wrap every response in ApiResponse<T> with success, data, and error fields
  • Define DTOs with serde and specta::Type and use #[serde(rename_all = "camelCase")]
  • Use verb+noun command names (get/create/update/delete) and DTO suffixes (CreateXDto, UpdateXDto, XDto)
  • Perform input validation at the command boundary; let business layer return anyhow::Result with context
  • Keep error messages concise and user-facing; avoid leaking internal errors or raw DB messages
  • Prefer reusing existing paginated types and return fields ready for direct rendering

Example use cases

  • Designing a CreateFactory endpoint with CreateFactoryDto, validation rules, and ApiResponse<CreateFactoryDto>
  • Converting legacy list endpoints to return a MaterialsPaginatedResult ready for table rendering
  • Standardizing error responses so the UI only needs to check ApiResponse.success and display ApiResponse.error
  • Defining DTOs for front-end forms that map directly to camelCase JSON and specta type metadata
  • Adding command-level validation to prevent SQLx errors and provide clear user-facing messages

FAQ

Why wrap responses in ApiResponse<T>?

A single envelope standardizes success, payload, and user-facing error text so clients can implement consistent handling.

Where should validation happen?

Validate at the command boundary before calling business logic; business functions should return anyhow::Result and add context on failure.