diff --git a/docs/assets/images/external-plugin.png b/docs/assets/images/external-plugin.png new file mode 100644 index 000000000000..bc5a3f595bd1 Binary files /dev/null and b/docs/assets/images/external-plugin.png differ diff --git a/docs/en/latest/config.json b/docs/en/latest/config.json index aec85b64c198..709791f06101 100644 --- a/docs/en/latest/config.json +++ b/docs/en/latest/config.json @@ -43,7 +43,9 @@ "plugins/serverless", "plugins/redirect", "plugins/echo", - "plugins/server-info" + "plugins/server-info", + "plugins/ext-plugin-pre-req", + "plugins/ext-plugin-post-req" ] }, { @@ -206,6 +208,10 @@ "type": "doc", "id": "plugin-develop" }, + { + "type": "doc", + "id": "external-plugin" + }, { "type": "doc", "id": "plugin-interceptors" diff --git a/docs/en/latest/external-plugin.md b/docs/en/latest/external-plugin.md new file mode 100644 index 000000000000..0eea264c3032 --- /dev/null +++ b/docs/en/latest/external-plugin.md @@ -0,0 +1,91 @@ +--- +title: External Plugin +--- + + + +## What are external plugin and plugin runner + +APISIX supports writing plugins in Lua. This type of plugins will be executed +inside APISIX. Sometimes you want to develop plugin in other languages, so APISIX +provides sidecars that loading your plugins and run them when the requests hit +APISIX. These sidecars are called plugin runners and your plugins are called +external plugins. + +## How does it work + +![external-plugin](../../../assets/images/external-plugin.png) + +When you configure a plugin runner in APISIX, APISIX will run the plugin runner +as a subprocess. The process will belong to the same user of the APISIX +process. When we restart or reload APISIX, the plugin runner will be restarted too. + +Once you have configured `ext-plugin-*` plugins for a given route, the requests +which hit the route will trigger RPC call from APISIX to the plugin runner via +unix socket. + +The plugin runner will handle the RPC call, create a fake request at its side, +run external plugins and return the result back to APISIX. + +The target external plugins and the execution order are configured in the `ext-plugin-*` +plugins. Like other plugins, they can be enabled and reconfigured on the fly. + +## Supported plugin runners + +Java: https://github.com/apache/apisix-java-plugin-runner +Go: https://github.com/apache/apisix-go-plugin-runner + +## Configuration for plugin runner in APISIX + +To run plugin runner in the prod, add the section below to `config.yaml`: + +```yaml +ext-plugin: + cmd: ["blah"] # replace it to the real runner executable according to the runner you choice +``` + +Then APISIX will manage the runner as its subprocess. + +Note: APISIX can't manage the runner on the Mac. It is fine, we can run the runner by ourselves +during development. + +During development, we want to run the runner separately so that we can restart it without +restarting APISIX first. + +By specifying the environment variable `APISIX_LISTEN_ADDRESS`, we can force the runner to +listen to a fixed address. +For instance: + +```bash +APISIX_LISTEN_ADDRESS=unix:/tmp/x.sock ./the_runner +``` + +will force the runner to listen to `/tmp/x.sock`. + +Then you need to configure APISIX to send RPC to the fixed address: + +```yaml +ext-plugin: + # cmd: ["blah"] # don't configure the executable! + path_for_test: "/tmp/x.sock" # without 'unix:' prefix +``` + +In the prod environment, `path_for_test` should not be used and the unix socket +path will be generated dynamically. diff --git a/docs/en/latest/plugin-develop.md b/docs/en/latest/plugin-develop.md index df072c07885f..bf6d26343e01 100644 --- a/docs/en/latest/plugin-develop.md +++ b/docs/en/latest/plugin-develop.md @@ -37,6 +37,9 @@ title: Plugin Develop - [Register public API](#register-public-api) - [Register control API](#register-control-api) +This documentation is about developing plugin in Lua. For other languages, +see [external plugin](./external-plugin.md). + ## where to put your plugins There are two ways to add new features based on APISIX. diff --git a/docs/en/latest/plugins/ext-plugin-post-req.md b/docs/en/latest/plugins/ext-plugin-post-req.md new file mode 100644 index 000000000000..7aac1bd170f6 --- /dev/null +++ b/docs/en/latest/plugins/ext-plugin-post-req.md @@ -0,0 +1,29 @@ +--- +title: ext-plugin-post-req +--- + + + +`ext-plugin-post-req` is almost the same as `ext-plugin-pre-req`. + +The only difference is that it runs after executing builtin Lua plugins and +before proxying to the upstream. + +See the documentation of [ext-plugin-pre-req](./ext-plugin-pre-req.md) for how to configure it. diff --git a/docs/en/latest/plugins/ext-plugin-pre-req.md b/docs/en/latest/plugins/ext-plugin-pre-req.md new file mode 100644 index 000000000000..e5a6fb76c6a3 --- /dev/null +++ b/docs/en/latest/plugins/ext-plugin-pre-req.md @@ -0,0 +1,100 @@ +--- +title: ext-plugin-pre-req +--- + + + +## Summary + +- [**Name**](#name) +- [**Attributes**](#attributes) +- [**How To Enable**](#how-to-enable) +- [**Test Plugin**](#test-plugin) +- [**Disable Plugin**](#disable-plugin) + +## Name + +The `ext-plugin-pre-req` runs specific external plugins in the plugin runner, before +executing any builtin Lua plugins. + +To know what is the plugin runner, see [external plugin](../external-plugin.md) section. + +The result of external plugins execution will affect the behavior of the current request. + +## Attributes + +| Name | Type | Requirement | Default | Valid | Description | +| --------- | ------------- | ----------- | ---------- | ------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------- | +| conf | array | optional | | [{"name": "ext-plugin-A", "value": "{\"enable\":\"feature\"}"}] | The plugins list which will be executed at the plugin runner with their configuration | + +## How To Enable + +Here's an example, enable this plugin on the specified route: + +```shell +curl -i http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/index.html", + "plugins": { + "ext-plugin-pre-req": { + "conf" : [ + {"name": "ext-plugin-A", "value": "{\"enable\":\"feature\"}"} + ] + }, + "upstream": { + "type": "roundrobin", + "nodes": { + "39.97.63.215:80": 1 + } + } +}' +``` + +## Test Plugin + +Use curl to access: + +```shell +curl -i http://127.0.0.1:9080/index.html +``` + +You will see the configured plugin runner will be hit and plugin `ext-plugin-A` +is executed at that side. + +## Disable Plugin + +When you want to disable this plugin, it is very simple, +you can delete the corresponding json configuration in the plugin configuration, +no need to restart the service, it will take effect immediately: + +```shell +curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1' -X PUT -d ' +{ + "uri": "/index.html", + "upstream": { + "type": "roundrobin", + "nodes": { + "39.97.63.215:80": 1 + } + } +}' +``` + +This plugin has been disabled now. It works for other plugins.