Skip to main content

Version: 3.10.x

a7-plugin-ext-plugin

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.

API7.ai Logo

The digital world is connected by APIs,
API7.ai exists to make APIs more efficient, reliable, and secure.

Sign up for API7 newsletter

Product

API7 Gateway

SOC2 Type IIISO 27001HIPAAGDPRRed Herring

Copyright © APISEVEN PTE. LTD 2019 – 2026. Apache, Apache APISIX, APISIX, and associated open source project names are trademarks of the Apache Software Foundation