API7 Docs

circuit-breaker recipe for API7 Gateway

Recipe skill for implementing circuit breaker patterns using the a7 CLI in API7 Enterprise Edition. Covers the api-breaker plugin, unhealthy thresholds,…

Overview

A circuit breaker prevents cascading failures by detecting unhealthy backend responses and temporarily stopping requests to the failing service. API7 EE implements this through the api-breaker plugin on routes.

Use the current service-backed route model:

  1. Create a service that owns the upstream backend.
  2. Create a route with service_id.
  3. Enable api-breaker on the route.

Plugin Configuration Reference

FieldRequiredDescription
break_response_codeYesHTTP status returned when the circuit is open
break_response_bodyNoResponse body returned when open
break_response_headersNoHeaders returned when open
unhealthy.http_statusesNoUpstream status codes counted as unhealthy
unhealthy.failuresNoConsecutive unhealthy responses before opening
healthy.http_statusesNoStatus codes counted as healthy for recovery
healthy.successesNoConsecutive healthy responses before closing
max_breaker_secNoMaximum circuit-open duration

Step-by-Step: Enable Circuit Breaker

1. Create a protected service

a7 service create --gateway-group default -f - <<'EOF'
{
  "id": "backend-service",
  "name": "backend-service",
  "upstream": {
    "type": "roundrobin",
    "nodes": [
      {"host": "backend", "port": 8080, "weight": 1}
    ]
  }
}
EOF

2. Create a route with api-breaker

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "protected-api",
  "name": "protected-api",
  "paths": ["/api/*"],
  "service_id": "backend-service",
  "plugins": {
    "api-breaker": {
      "break_response_code": 502,
      "unhealthy": {
        "http_statuses": [500, 502, 503],
        "failures": 3
      },
      "healthy": {
        "http_statuses": [200],
        "successes": 3
      },
      "max_breaker_sec": 300
    }
  }
}
EOF

After three consecutive 500/502/503 responses, the circuit opens and returns 502 immediately. After cooldown, API7 EE tests recovery and closes the circuit after enough healthy responses.

3. Custom error response

a7 route update protected-api --gateway-group default -f - <<'EOF'
{
  "id": "protected-api",
  "name": "protected-api",
  "paths": ["/api/*"],
  "service_id": "backend-service",
  "plugins": {
    "api-breaker": {
      "break_response_code": 503,
      "break_response_body": "{\"error\": \"service temporarily unavailable\", \"retry_after\": 30}",
      "break_response_headers": [
        {"key": "Content-Type", "value": "application/json"},
        {"key": "Retry-After", "value": "30"}
      ],
      "unhealthy": {
        "http_statuses": [500, 502, 503, 504],
        "failures": 5
      },
      "healthy": {
        "http_statuses": [200, 201, 204],
        "successes": 2
      },
      "max_breaker_sec": 60
    }
  }
}
EOF

4. Combine with health checks

For production, define health checks on the service upstream and keep api-breaker on the route. Health checks manage node health; the circuit breaker protects this route from repeated upstream failures.

a7 service create --gateway-group default -f - <<'EOF'
{
  "id": "monitored-backend-service",
  "name": "monitored-backend-service",
  "upstream": {
    "type": "roundrobin",
    "nodes": [
      {"host": "backend-1", "port": 8080, "weight": 1},
      {"host": "backend-2", "port": 8080, "weight": 1}
    ],
    "checks": {
      "active": {
        "type": "http",
        "http_path": "/health",
        "healthy": {"interval": 5, "successes": 2},
        "unhealthy": {"interval": 3, "http_failures": 3}
      }
    }
  }
}
EOF

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "api",
  "name": "api",
  "paths": ["/api/*"],
  "service_id": "monitored-backend-service",
  "plugins": {
    "api-breaker": {
      "break_response_code": 503,
      "unhealthy": {
        "http_statuses": [500, 502, 503],
        "failures": 3
      },
      "healthy": {
        "http_statuses": [200],
        "successes": 3
      }
    }
  }
}
EOF

Config Sync

version: "1"
services:
  - id: backend-service
    name: backend-service
    upstream:
      type: roundrobin
      nodes:
        - host: backend
          port: 8080
          weight: 1
routes:
  - id: protected-api
    name: protected-api
    paths:
      - /api/*
    service_id: backend-service
    plugins:
      api-breaker:
        break_response_code: 503
        break_response_body: '{"error": "service unavailable"}'
        break_response_headers:
          - key: Content-Type
            value: application/json
          - key: Retry-After
            value: "30"
        unhealthy:
          http_statuses: [500, 502, 503]
          failures: 3
        healthy:
          http_statuses: [200]
          successes: 3
        max_breaker_sec: 300

Troubleshooting

SymptomCauseFix
Circuit never opensunhealthy.http_statuses misses the real error codeAdd the actual upstream error codes
Circuit stays open too longmax_breaker_sec too highLower max_breaker_sec
Circuit flapsThreshold too low for intermittent errorsIncrease unhealthy.failures
API7 returns 502 outside breaker responseBackend is unreachableConnection errors also count toward unhealthy thresholds
Recovery too slowhealthy.successes too highLower healthy.successes
Route not using breakerPlugin attached to the wrong routeVerify with a7 route get <id> -o json
Command failed with 403RBAC permission issueEnsure your token can modify routes in the gateway group

This page is generated from a7-recipe-circuit-breaker/SKILL.md in the api7/a7 repository. Browse all skills on the AI Agent Skills page.