pluginagentmarketplace/custom-plugin-system-design · Archived

api-architecture

Production-grade API architecture skill for REST, gRPC, GraphQL design, versioning, and security patterns

First seen Jul 11, 2026

Installation

$ npx skills add pluginagentmarketplace/custom-plugin-system-design --skill api-architecture

Stronger alternatives

This repository is archived — consider an actively maintained alternative.

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from pluginagentmarketplace/custom-plugin-system-design.

npx skills add pluginagentmarketplace/custom-plugin-system-design

Browse all from pluginagentmarketplace/custom-plugin-system-design

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Also listed on

Alternate registries and mirrors of this skill.

Repository health

Stars 4
License LICENSE
Default branch main
Open issues 0
Status Archived

Package contents

Files included with this skill beyond the listing page.

  • skill md SKILL.md 9,891 B
  • docs SUMMARY.md 129 B

History

  1. First seen on skills.sh
  2. First recorded snapshot · 1 installs

SKILL.md

API Architecture Skill

Purpose: Atomic skill for API design with comprehensive validation, error handling, and security patterns.

Skill Identity

Attribute Value
Scope REST, gRPC, GraphQL Design
Responsibility Single: API contract and protocol design
Invocation Skill("api-architecture")

Parameter Schema

Input Validation

parameters:
  api_context:
    type: object
    required: true
    properties:
      protocol:
        type: string
        enum: [REST, gRPC, GraphQL, hybrid]
        required: true
      resources:
        type: array
        items:
          type: object
          properties:
            name: { type: string, pattern: "^[a-z][a-z0-9-]*$" }
            operations: { type: array, items: { type: string } }
        minItems: 1
      consumers:
        type: array
        items:
          type: string
          enum: [web, mobile, third_party, internal, iot]
      security:
        type: object
        properties:
          auth_method: { type: string, enum: [oauth2, api_key, jwt, mtls] }
          rate_limiting: { type: boolean, default: true }
      constraints:
        type: object
        properties:
          max_latency_ms: { type: integer, minimum: 1 }
          backward_compatible: { type: boolean, default: true }

validation_rules:
  - name: "resource_naming"
    rule: "resources[*].name matches /^[a-z][a-z0-9-]*$/"
    error: "Resource names must be lowercase with hyphens"
  - name: "public_api_security"
    rule: "consumers includes 'third_party' implies auth_method is set"
    error: "Public APIs require authentication"

Output Schema

output:
  type: object
  properties:
    endpoints:
      type: array
      items:
        type: object
        properties:
          method: { type: string }
          path: { type: string }
          request_schema: { type: object }
          response_schema: { type: object }
          status_codes: { type: array }
    openapi_spec:
      type: string
      format: yaml
    security_config:
      type: object
      properties:
        auth: { type: object }
        rate_limits: { type: object }
        cors: { type: object }

Core Patterns

REST Design Principles

Resource Naming:
├── Nouns, plural: /users, /orders
├── Hierarchical: /users/{id}/orders
├── Actions as sub-resources: /orders/{id}/cancel
├── Query params for filtering: ?status=active
└── Kebab-case: /user-profiles

HTTP Methods:
├── GET     → Read (idempotent, cacheable)
├── POST    → Create (not idempotent)
├── PUT     → Replace (idempotent)
├── PATCH   → Update partial (idempotent)
├── DELETE  → Remove (idempotent)
├── HEAD    → Metadata only
└── OPTIONS → CORS preflight

Status Codes:
├── 200 OK: Successful GET/PUT/PATCH
├── 201 Created: Successful POST (with Location header)
├── 204 No Content: Successful DELETE
├── 400 Bad Request: Validation error
├── 401 Unauthorized: Not authenticated
├── 403 Forbidden: Not authorized
├── 404 Not Found: Resource missing
├── 409 Conflict: State conflict
├── 422 Unprocessable: Semantic error
├── 429 Too Many Requests: Rate limited
├── 500 Internal Error: Server bug
├── 502 Bad Gateway: Upstream error
├── 503 Unavailable: Maintenance
└── 504 Gateway Timeout: Upstream timeout

gRPC Patterns

Service Types:
├── Unary: request → response
├── Server Streaming: request → stream<response>
├── Client Streaming: stream<request> → response
└── Bidirectional: stream<request> → stream<response>

Proto Best Practices:
├── Use proto3
├── Package: company.service.v1
├── Reserve deleted field numbers
├── Use well-known types
└── Backward compatible changes only

GraphQL Patterns

Schema Design:
├── Types: Clear domain modeling
├── Queries: Read operations
├── Mutations: Write operations
├── Subscriptions: Real-time
└── Input types: Separate from output

Security:
├── Query depth limiting
├── Complexity analysis
├── Field-level authorization
├── Persisted queries
└── Rate limiting by complexity

Retry Logic

Client Retry Configuration

retry_config:
  http_client:
    max_attempts: 3
    initial_delay_ms: 100
    max_delay_ms: 10000
    multiplier: 2.0
    jitter_factor: 0.2

  retryable_status_codes:
    - 429  # Rate limited (use Retry-After)
    - 502  # Bad gateway
    - 503  # Service unavailable
    - 504  # Gateway timeout

  non_retryable:
    - 400  # Bad request
    - 401  # Unauthorized
    - 403  # Forbidden
    - 404  # Not found
    - 409  # Conflict
    - 422  # Unprocessable

  idempotency:
    header: "Idempotency-Key"
    required_for: [POST, PATCH]
    cache_ttl_seconds: 86400

Logging & Observability

Log Format

log_schema:
  level: { type: string }
  timestamp: { type: string, format: ISO8601 }
  skill: { type: string, value: "api-architecture" }
  request_id: { type: string }
  event:
    type: string
    enum:
      - endpoint_designed
      - schema_generated
      - validation_passed
      - security_configured
      - rate_limit_set
  context:
    type: object
    properties:
      method: { type: string }
      path: { type: string }
      protocol: { type: string }

example:
  level: INFO
  request_id: "req_abc123"
  event: endpoint_designed
  context:
    method: POST
    path: /v1/users
    protocol: REST

Metrics

metrics:
  - name: api_request_total
    type: counter
    labels: [method, path, status]

  - name: api_request_duration_seconds
    type: histogram
    labels: [method, path]
    buckets: [0.005, 0.01, 0.05, 0.1, 0.5, 1, 5]

  - name: api_rate_limit_exceeded_total
    type: counter
    labels: [client_id, path]

  - name: api_error_total
    type: counter
    labels: [method, path, error_code]

Troubleshooting

Common Issues

Issue Cause Resolution
400 errors Schema mismatch Validate against OpenAPI
401 errors Token expired Implement refresh flow
429 errors Rate limit hit Implement backoff, cache
CORS errors Missing headers Configure allowed origins
Slow response N+1 queries Batch, DataLoader

Debug Checklist

□ Request matches OpenAPI spec?
□ Auth token valid and not expired?
□ Rate limit headers checked?
□ Error response format consistent?
□ Retry-After header on 429/503?
□ CORS configured for all origins?
□ Pagination implemented?

Unit Test Templates

API Validation Tests

# test_api_architecture.py

def test_valid_rest_resource():
    params = {
        "api_context": {
            "protocol": "REST",
            "resources": [
                {"name": "users", "operations": ["list", "get", "create", "update", "delete"]},
                {"name": "orders", "operations": ["list", "get", "create"]}
            ],
            "consumers": ["web", "mobile"],
            "security": {"auth_method": "oauth2", "rate_limiting": True}
        }
    }
    result = validate_parameters(params)
    assert result.valid == True

def test_invalid_resource_naming():
    params = {
        "api_context": {
            "protocol": "REST",
            "resources": [
                {"name": "Users", "operations": ["list"]}  # Should be lowercase
            ]
        }
    }
    result = validate_parameters(params)
    assert result.valid == False
    assert "lowercase" in result.errors[0]

def test_public_api_requires_auth():
    params = {
        "api_context": {
            "protocol": "REST",
            "resources": [{"name": "data", "operations": ["list"]}],
            "consumers": ["third_party"]
            # Missing security.auth_method
        }
    }
    result = validate_parameters(params)
    assert result.valid == False
    assert "authentication" in result.errors[0]

def test_endpoint_generation():
    resource = {"name": "users", "operations": ["list", "get", "create"]}
    endpoints = generate_endpoints(resource)

    assert endpoints[0] == {"method": "GET", "path": "/v1/users"}
    assert endpoints[1] == {"method": "GET", "path": "/v1/users/{id}"}
    assert endpoints[2] == {"method": "POST", "path": "/v1/users"}

Status Code Tests

def test_status_code_for_create():
    operation = "create"
    result = determine_status_codes(operation)
    assert 201 in result.success
    assert 400 in result.client_error
    assert 409 in result.client_error  # Conflict for duplicate

def test_rate_limit_headers():
    response = generate_rate_limit_headers(
        limit=1000,
        remaining=998,
        reset_epoch=1640995200
    )
    assert response["X-RateLimit-Limit"] == "1000"
    assert response["X-RateLimit-Remaining"] == "998"
    assert response["X-RateLimit-Reset"] == "1640995200"

def test_error_response_format():
    error = generate_error_response(
        code="VALIDATION_ERROR",
        message="Invalid email format",
        details=[{"field": "email", "reason": "must be valid email"}],
        request_id="req_123"
    )
    assert error["error"]["code"] == "VALIDATION_ERROR"
    assert error["error"]["request_id"] == "req_123"
    assert len(error["error"]["details"]) == 1

Version History

Version Date Changes
2.0.0 2025-01 Production-grade rewrite with security patterns
1.0.0 2024-12 Initial release