Token导航 LogoToken导航TokenDH.com
前端设计需要联网github未标认证来源可访问clear审计通过

api-contract-normalizerAPI contract normalizer ORM

Agent Skill

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

总安装

2,250

周安装

91

GitHub Stars

33

下载量

706
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

3

许可证

MIT

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:api-contract-normalizer(API contract normalizer ORM)
来源仓库:https://github.com/patricio0312rev/skills
仓库路径:skills/api-contract-normalizer
安装命令:
npx skills add https://github.com/patricio0312rev/skills --skill api-contract-normalizer
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/patricio0312rev/skills --skill api-contract-normalizer

简介

标准化 API 响应格式、分页与错误处理,提升跨端点的一致性与开发者体验。

  • 适用于多服务聚合场景,自动转换响应结构并生成共享 TypeScript 类型定义。
  • 使用时需审计现有 API 不一致处,制定统一标准并分阶段实施迁移计划。
  • 安装方式:通过 npx skills add 从指定仓库获取,兼容 Codex、Claude 等宿主环境。
  • 注意:中间件应在网关或代理层部署,避免污染业务逻辑代码。

SKILL.md

API Contract Normalizer

Standardize API contracts across all endpoints for consistency and developer experience.

Core Workflow

  1. Audit existing APIs: Document current inconsistencies
  2. Define standards: Response format, pagination, errors, status codes
  3. Create shared types: TypeScript interfaces for all contracts
  4. Build middleware: Normalize responses automatically
  5. Document contract: OpenAPI spec with examples
  6. Migration plan: Phased rollout strategy
  7. Versioning: API version strategy

Standard Response Envelope

// types/api-contract.ts
export interface ApiResponse<T = unknown> {
  success: boolean;
  data?: T;
  error?: ApiError;
  meta?: ResponseMeta;
}

export interface ApiError {
  code: string;
  message: string;
  details?: Record<string, string[] | string>;
  trace_id?: string;
}

export interface ResponseMeta {
  timestamp: string;
  request_id: string;
  version: string;
}

export interface PaginatedResponse<T> extends ApiResponse<T[]> {
  meta: ResponseMeta & PaginationMeta;
}

export interface PaginationMeta {
  page: number;
  limit: number;
  total: number;
  total_pages: number;
  has_next: boolean;
  has_prev: boolean;
}

Pagination Standards

// Standard pagination query params
interface PaginationQuery {
  page: number;      // 1-indexed, default: 1
  limit: number;     // default: 10, max: 100
  sort_by?: string;  // field name
  sort_order?: 'asc' | 'desc'; // default: 'desc'
}

// Standard pagination response
{
  "success": true,
  "data": [...],
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 156,
    "total_pages": 16,
    "has_next": true,
    "has_prev": false
  }
}

// Cursor-based pagination (for large datasets)
interface CursorPaginationQuery {
  cursor?: string;
  limit: number;
}

interface CursorPaginationMeta {
  next_cursor?: string;
  prev_cursor?: string;
  has_more: boolean;
}

Error Standards

// Error taxonomy
export enum ErrorCode {
  // Client errors (4xx)
  VALIDATION_ERROR = 'VALIDATION_ERROR',
  UNAUTHORIZED = 'UNAUTHORIZED',
  FORBIDDEN = 'FORBIDDEN',
  NOT_FOUND = 'NOT_FOUND',
  CONFLICT = 'CONFLICT',
  RATE_LIMIT_EXCEEDED = 'RATE_LIMIT_EXCEEDED',

  // Server errors (5xx)
  INTERNAL_ERROR = 'INTERNAL_ERROR',
  SERVICE_UNAVAILABLE = 'SERVICE_UNAVAILABLE',
  TIMEOUT = 'TIMEOUT',
}

// Error to HTTP status mapping
export const ERROR_STATUS_MAP: Record<ErrorCode, number> = {
  VALIDATION_ERROR: 400,
  UNAUTHORIZED: 401,
  FORBIDDEN: 403,
  NOT_FOUND: 404,
  CONFLICT: 409,
  RATE_LIMIT_EXCEEDED: 429,
  INTERNAL_ERROR: 500,
  SERVICE_UNAVAILABLE: 503,
  TIMEOUT: 504,
};

// Standard error responses
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid request data",
    "details": {
      "email": ["Invalid email format"],
      "age": ["Must be at least 18"]
    },
    "trace_id": "abc123"
  }
}

Response Normalization Middleware

// middleware/normalize-response.ts
import { Request, Response, NextFunction } from "express";

export function normalizeResponse() {
  return (req: Request, res: Response, next: NextFunction) => {
    const originalJson = res.json.bind(res);

    res.json = function (data: any) {
      // Already normalized
      if (data.success !== undefined) {
        return originalJson(data);
      }

      // Normalize success response
      const normalized: ApiResponse = {
        success: true,
        data,
        meta: {
          timestamp: new Date().toISOString(),
          request_id: req.id,
          version: "v1",
        },
      };

      return originalJson(normalized);
    };

    next();
  };
}

// Error normalization middleware
export function normalizeError() {
  return (err: Error, req: Request, res: Response, next: NextFunction) => {
    const error: ApiError = {
      code: err.name || "INTERNAL_ERROR",
      message: err.message || "An unexpected error occurred",
      trace_id: req.id,
    };

    if (err instanceof ValidationError) {
      error.details = err.details;
    }

    const statusCode = ERROR_STATUS_MAP[error.code] || 500;

    res.status(statusCode).json({
      success: false,
      error,
      meta: {
        timestamp: new Date().toISOString(),
        request_id: req.id,
        version: "v1",
      },
    });
  };
}

Status Code Standards

// Standard status codes by operation
const STATUS_CODES = {
  // Success
  OK: 200, // GET, PUT, PATCH success
  CREATED: 201, // POST success
  NO_CONTENT: 204, // DELETE success

  // Client errors
  BAD_REQUEST: 400, // Validation errors
  UNAUTHORIZED: 401, // Missing/invalid auth
  FORBIDDEN: 403, // Insufficient permissions
  NOT_FOUND: 404, // Resource not found
  CONFLICT: 409, // Duplicate/conflict
  UNPROCESSABLE: 422, // Semantic errors
  TOO_MANY_REQUESTS: 429, // Rate limit

  // Server errors
  INTERNAL_ERROR: 500, // Unexpected errors
  SERVICE_UNAVAILABLE: 503, // Temporarily down
  GATEWAY_TIMEOUT: 504, // Upstream timeout
};

Versioning Strategy

// URL versioning (recommended)
/api/v1/users
/api/v2/users

// Header versioning
Accept: application/vnd.api.v1+json

// Query param versioning (not recommended)
/api/users?version=1

// Version middleware
export function apiVersion(version: string) {
  return (req: Request, res: Response, next: NextFunction) => {
    req.apiVersion = version;
    res.setHeader('X-API-Version', version);
    next();
  };
}

// Route versioning
app.use('/api/v1', apiVersion('v1'), v1Router);
app.use('/api/v2', apiVersion('v2'), v2Router);

Migration Strategy

# API Contract Migration Plan

## Phase 1: Add Normalization (Week 1-2)

- [ ] Deploy normalization middleware
- [ ] Run alongside existing responses
- [ ] Monitor for issues
- [ ] No breaking changes yet

## Phase 2: Deprecation Notice (Week 3-4)

- [ ] Add deprecation headers
- [ ] Update documentation
- [ ] Notify API consumers
- [ ] Provide migration guide

## Phase 3: Dual Format Support (Week 5-8)

- [ ] Support both old and new formats
- [ ] Add ?format=v2 query param
- [ ] Track adoption metrics
- [ ] Help consumers migrate

## Phase 4: Switch Default (Week 9-10)

- [ ] New format becomes default
- [ ] Old format requires ?format=v1
- [ ] Final migration reminders
- [ ] Extended support period

## Phase 5: Remove Old Format (Week 12+)

- [ ] Remove old format support
- [ ] Clean up legacy code
- [ ] Update all documentation
- [ ] Celebrate consistency! 🎉

Contract Documentation

# openapi.yaml
openapi: 3.0.0
info:
  title: Standardized API
  version: 1.0.0
  description: All endpoints follow this contract

components:
  schemas:
    ApiResponse:
      type: object
      required: [success]
      properties:
        success:
          type: boolean
        data:
          type: object
        error:
          $ref: "#/components/schemas/ApiError"
        meta:
          $ref: "#/components/schemas/ResponseMeta"

    ApiError:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          enum: [VALIDATION_ERROR, UNAUTHORIZED, ...]
        message:
          type: string
        details:
          type: object
          additionalProperties: true
        trace_id:
          type: string

    PaginationMeta:
      type: object
      required: [page, limit, total, total_pages]
      properties:
        page: { type: integer }
        limit: { type: integer }
        total: { type: integer }
        total_pages: { type: integer }
        has_next: { type: boolean }
        has_prev: { type: boolean }

Shared Utilities

// utils/api-response.ts
export class ApiResponseBuilder {
  static success<T>(data: T, meta?: Partial<ResponseMeta>): ApiResponse<T> {
    return {
      success: true,
      data,
      meta: {
        timestamp: new Date().toISOString(),
        ...meta,
      },
    };
  }

  static paginated<T>(
    data: T[],
    pagination: PaginationMeta
  ): PaginatedResponse<T> {
    return {
      success: true,
      data,
      meta: {
        timestamp: new Date().toISOString(),
        ...pagination,
      },
    };
  }

  static error(code: ErrorCode, message: string, details?: any): ApiResponse {
    return {
      success: false,
      error: { code, message, details },
      meta: {
        timestamp: new Date().toISOString(),
      },
    };
  }
}

Best Practices

  1. Consistent envelope: All responses use same structure
  2. Type safety: Shared types across frontend/backend
  3. Clear errors: Descriptive codes and messages
  4. Standard pagination: Same format for all lists
  5. Versioning: Plan for API evolution
  6. Documentation: OpenAPI spec as source of truth
  7. Gradual migration: Don't break existing clients
  8. Monitoring: Track adoption and errors

Output Checklist

  • Standard response envelope defined
  • Error taxonomy documented
  • Pagination format standardized
  • Status code mapping
  • Normalization middleware
  • Shared TypeScript types
  • Versioning strategy
  • OpenAPI specification
  • Migration plan with phases
  • Consumer communication plan

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

04

需要参考平台分布和安装热度时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

补充不同宿主或平台的使用分布数据

能力 5

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Claude Code

30.92%
按下载量换算218

Gemini CLI

22.12%
按下载量换算156

Antigravity

19.45%
按下载量换算137

windsurf

12.99%
按下载量换算92

github-copilot

7.61%
按下载量换算54

Codex

3.69%
按下载量换算26

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

来源信息

继续浏览同类 Skills