API7 Docs

ext-plugin plugin for API7 Gateway

Skill for configuring the API7 Enterprise Edition external plugin system (ext-plugin-pre-req, ext-plugin-post-req, ext-plugin-post-resp) via the a7 CLI.…

Overview

The API7 Enterprise Edition (API7 EE) external plugin system lets you run plugins written in Go, Java, Python, or JavaScript via a Plugin Runner process. API7 EE communicates with the runner over a Unix socket using FlatBuffers serialization.

Three plugins control when external plugins execute:

PluginPhasePriorityDescription
ext-plugin-pre-reqrewrite12000Before built-in Lua plugins
ext-plugin-post-reqaccess−3000After Lua plugins, before upstream
ext-plugin-post-respbefore_proxy−4000After upstream response received

When to Use

  • Implement custom logic in Go, Java, or Python instead of Lua.
  • Reuse existing business logic from non-Lua codebases.
  • Apply pre-processing (auth, validation) or post-processing (response transform).
  • Teams that prefer statically-typed languages over Lua.

Plugin Configuration Reference

All three plugins share the same schema:

FieldTypeRequiredDefaultDescription
confarrayNoList of external plugins to execute
conf[].namestringYesPlugin identifier (1–128 chars)
conf[].valuestringYesJSON string configuration passed to the plugin
allow_degradationbooleanNofalseWhen true, requests continue if runner is unavailable

Plugin Runner Architecture

┌─────────────┐    Unix Socket    ┌───────────────┐
│   API7 EE   │ ◄──────────────► │ Plugin Runner  │
│ (Data Plane)│   FlatBuffers    │ (Go/Java/Py)   │
└─────────────┘                   └───────────────┘
  1. API7 EE starts the runner as a subprocess (managed lifecycle).
  2. On ext-plugin-* trigger, API7 EE sends an RPC over Unix socket.
  3. Runner executes external plugins and returns the result.
  4. API7 EE applies modifications (headers, body, status) to the request/response.

RPC Protocol

  • PrepareConf: Syncs plugin configuration → returns a conf token (cached).
  • HTTPReqCall: Per-request execution with serialized HTTP data + conf token.
  • ExtraInfo: Runner can request additional data (variables, body, response).

Supported Plugin Runners

LanguageRepositoryStatus
Goapache/apisix-go-plugin-runnerGA
Javaapache/apisix-java-plugin-runnerGA
Pythonapache/apisix-python-plugin-runnerExperimental
JavaScriptzenozeng/apisix-javascript-plugin-runnerCommunity

API7 EE Configuration

Production Setup

API7 EE manages the runner as a subprocess. This is configured in the gateway group's configuration (via Dashboard or CLI sync).

ext-plugin:
  cmd: ["/path/to/runner-executable", "run"]

Runner-Specific Commands

# Go runner
ext-plugin:
  cmd: ["/opt/api7-go-runner", "run"]

# Java runner
ext-plugin:
  cmd: ["java", "-jar", "-Xmx1g", "-Xms1g", "/opt/api7-runner.jar"]

# Python runner
ext-plugin:
  cmd: ["python3", "/opt/api7-python-runner/apisix/main.py", "start"]

Development Setup (Standalone Runner)

For local development, run the runner separately:

# API7 EE configuration — do NOT set cmd
ext-plugin:
  path_for_test: "/tmp/runner.sock"
# Start runner manually
API7_LISTEN_ADDRESS=unix:/tmp/runner.sock ./runner run

Environment Variables

Pass environment variables to the runner:

nginx_config:
  envs:
    - MY_ENV_VAR
    - DATABASE_URL

Step-by-Step Examples

1. Single External Plugin

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "ext-auth",
  "uri": "/api/*",
  "plugins": {
    "ext-plugin-pre-req": {
      "conf": [
        {"name": "AuthFilter", "value": "{\"token_required\":true}"}
      ]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

2. Multiple External Plugins with Degradation

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "ext-chain",
  "uri": "/api/*",
  "plugins": {
    "ext-plugin-pre-req": {
      "conf": [
        {"name": "AuthFilter", "value": "{\"token_required\":true}"},
        {"name": "RateLimiter", "value": "{\"requests_per_second\":100}"}
      ],
      "allow_degradation": true
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

3. All Three Plugin Types (Full Request Lifecycle)

a7 route create --gateway-group default -f - <<'EOF'
{
  "id": "full-ext",
  "uri": "/api/*",
  "plugins": {
    "ext-plugin-pre-req": {
      "conf": [{"name": "auth-check", "value": "{}"}]
    },
    "ext-plugin-post-req": {
      "conf": [{"name": "request-transform", "value": "{}"}]
    },
    "ext-plugin-post-resp": {
      "conf": [{"name": "response-logger", "value": "{}"}]
    }
  },
  "upstream": {
    "type": "roundrobin",
    "nodes": [{"host": "backend", "port": 8080, "weight": 1}]
  }
}
EOF

Execution order: pre-req → (Lua plugins) → post-req → (upstream) → post-resp.

Config Sync Example

version: "1"
gateway_group: default
routes:
  - id: ext-plugin-demo
    uri: /api/*
    plugins:
      ext-plugin-pre-req:
        conf:
          - name: AuthFilter
            value: '{"token_required":true}'
        allow_degradation: true
    upstream:
      type: roundrobin
      nodes:
        - host: backend
          port: 8080
          weight: 1

Compatibility Matrix

Featureext-plugin-pre-reqext-plugin-post-reqext-plugin-post-resp
Phaserewriteaccessbefore_proxy
RunsBefore Lua pluginsAfter Lua pluginsAfter upstream response
proxy-mirror
proxy-cache
proxy-control
mTLS to upstream

ext-plugin-post-resp limitation: Uses internal transport mechanism, which makes it incompatible with proxy-mirror, proxy-cache, proxy-control, and mTLS to upstream.

Performance Considerations

  • Unix socket + FlatBuffers: Low-latency IPC, no TCP overhead.
  • Conf token caching: PrepareConf called once per config change, not per request.
  • Process management: API7 EE sends SIGTERM then SIGKILL (1s grace) on reload.
  • Degradation mode: Enable allow_degradation: true for non-critical plugins.
  • Connection reuse: Runner should reuse socket connections.

Troubleshooting

SymptomCauseFix
failed to receive RPC_PREPARE_CONFRunner not listening or socket path mismatchVerify socket path in configuration matches API7_LISTEN_ADDRESS
503 Service UnavailableRunner crashed or not startedCheck runner logs; verify cmd path is correct
Runner not receiving env varsNginx hides env vars by defaultAdd vars to nginx_config.envs in gateway group configuration
Slow response timesExternal plugin doing heavy workProfile runner; consider async processing
ext-plugin-post-resp conflictsIncompatible with proxy-* pluginsUse ext-plugin-post-req instead, or remove proxy-mirror/cache

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