This is an automated email from the ASF dual-hosted git repository.
tokers pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-go-plugin-runner.git
The following commit(s) were added to refs/heads/master by this push:
new 6bf4954 docs: add getting-started.md (#20)
6bf4954 is described below
commit 6bf4954f22cc902f91674190d4a730176f35d735
Author: 罗泽轩 <[email protected]>
AuthorDate: Thu Jul 8 19:00:48 2021 +0800
docs: add getting-started.md (#20)
---
docs/assets/images/runner-overview.png | Bin 0 -> 524459 bytes
docs/en/latest/getting-started.md | 194 ++++++++++++++++++++++++++++++++-
2 files changed, 193 insertions(+), 1 deletion(-)
diff --git a/docs/assets/images/runner-overview.png
b/docs/assets/images/runner-overview.png
new file mode 100644
index 0000000..3f6f391
Binary files /dev/null and b/docs/assets/images/runner-overview.png differ
diff --git a/docs/en/latest/getting-started.md
b/docs/en/latest/getting-started.md
index 6b1bd64..8292068 100644
--- a/docs/en/latest/getting-started.md
+++ b/docs/en/latest/getting-started.md
@@ -26,4 +26,196 @@ title: Getting started
* Go (>= 1.15)
* APISIX (>= 2.7.0)
-<!-- TODO -->
+## Installation
+
+For now, we need to use Go Runner as a library. `cmd/go-runner` in this
project is an official example showing how to use the Go Runner SDK.
+We will also support loading pre-compiled plugins through the Go Plugin
mechanism later.
+
+## Development
+
+### Developing with the Go Runner SDK
+
+```bash
+$ tree cmd/go-runner
+cmd/go-runner
+├── main.go
+├── main_test.go
+├── plugins
+│ ├── say.go
+│ └── say_test.go
+└── version.go
+```
+
+Above is the directory structure of the official example. `main.go` is the
entry point, where the most critical part is:
+
+```go
+cfg := runner.RunnerConfig{}
+...
+runner.Run(cfg)
+```
+
+`RunnerConfig` can be used to control the log level and log output location.
+
+`runner.Run` will make the application listen to the target socket path,
receive requests and execute the registered plugins. The application will
remain in this state until it exits.
+
+Then let's look at the plugin implementation.
+
+Open `plugins/say.go`.
+
+```go
+func init() {
+ err := plugin.RegisterPlugin(&Say{})
+ if err ! = nil {
+ log.Fatalf("failed to register plugin say: %s", err)
+ }
+}
+```
+
+Since `main.go` imports the plugins package,
+
+```go
+import (
+ ...
+ _ "github.com/apache/apisix-go-plugin-runner/cmd/go-runner/plugins"
+ ...
+)
+```
+
+in this way we register `Say` with `plugin.RegisterPlugin` before executing
`runner.Run`.
+
+`Say` needs to implement the following methods:
+
+The `Name` method returns the plugin name.
+
+```
+func (p *Say) Name() string {
+ return "say"
+}
+```
+
+`ParseConf` will be called when the plugin configuration changes, parsing the
configuration and returning the plugin specific configuration.
+
+```
+func (p *Say) ParseConf(in []byte) (interface{}, error) {
+ conf := SayConf{}
+ err := json.Unmarshal(in, &conf)
+ return conf, err
+}
+```
+
+The configuration of the plugin looks like this.
+
+```
+type SayConf struct {
+ Body string `json: "body"`
+}
+```
+
+`Filter` will be executed on every request with the say plugin configured.
+
+```
+func (p *Say) Filter(conf interface{}, w http.ResponseWriter, r
pkgHTTP.Request) {
+ body := conf.(SayConf).
+ if len(body) == 0 {
+ return
+ }
+
+ w.Header().Add("X-Resp-A6-Runner", "Go")
+ _, err := w.Write([]byte(body))
+ if err ! = nil {
+ log.Errorf("failed to write: %s", err)
+ }
+}
+```
+
+We can see that the Filter takes the value of the body set in the
configuration as the response body. If we respond directly in the plugin, it
will response directly in the APISIX without touching the upstream.
+
+Here you can read the API documentation provided by the Go Runner SDK:
https://pkg.go.dev/github.com/apache/apisix-go-plugin-runner
+
+After building the application (`make build` in the example), we need to set
two environment variables at runtime.
+
+1. `APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock`
+2. `APISIX_CONF_EXPIRE_TIME=3600`
+
+Like this.
+
+```
+APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock APISIX_CONF_EXPIRE_TIME=3600
./go-runner run
+```
+
+The application will listen to `/tmp/runner.sock` when it runs.
+
+### Setting up APISIX (debugging)
+
+First you need to have APISIX on your machine, which needs to be on the same
instance as Go Runner.
+
+
+
+The diagram above shows the workflow of APISIX on the left, while the plugin
runner on the right is responsible for running external plugins written in
different languages. apisix-go-plugin-runner is one such runner that supports
Go.
+
+When you configure a plugin runner in APISIX, APISIX will treat the plugin
runner as a child process of its own. This sub-process belongs to the same user
as the APISIX process. When we restart or reload APISIX, the plugin runner will
also be restarted.
+
+If you configure the ext-plugin-* plugin for a given route, a request to hit
that route will trigger APISIX to make an RPC call to the plugin runner via a
unix socket. The call is broken down into two phases.
+
+- ext-plugin-pre-req: before executing most of the APISIX built-in plugins
(Lua language plugins)
+- ext-plugin-post-req: after the execution of the APISIX built-in plugins (Lua
language plugins)
+
+Configure the timing of plugin runner execution as needed.
+
+The plugin runner handles the RPC calls, creates a mock request from it, then
runs the plugins written in other languages and returns the results to APISIX.
+
+The order of execution of these plugins is defined in the ext-plugin-* plugin
configuration. Like other plugins, they can be enabled and disabled on the fly.
+
+Let's go back to the examples. To show how to develop Go plugins, we first set
APISIX into debug mode. Add the following configuration to config.yaml.
+
+```
+ext-plugin:
+ path_for_test: /tmp/runner.sock
+```
+
+This configuration means that after hitting a routing rule, APISIX will make
an RPC request to /tmp/runner.sock.
+
+Next, prepare the routing rule.
+
+```
+curl http://127.0.0.1:9080/apisix/admin/routes/1 -H 'X-API-KEY:
edd1c9f034335f136f87ad84b625c8f1' -X PUT -d '
+{
+ "uri": "/get",
+ "plugins": {
+ "ext-plugin-pre-req": {
+ "conf": [
+ { "name": "say", "value":"{\"body\":\"hello\"}"}
+ ]
+ }
+ },
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:1980": 1
+ }
+ }
+}
+'
+```
+
+Note that the plugin name is configured in `name` and the plugin configuration
(after JSON serialization) is placed in `value`.
+
+If you see `refresh cache and try again` warning on APISIX side and `key not
found` warning on Runner side during development, this is due to configuration
cache inconsistency. Because the Runner is not managed by APISIX in the
development state, the internal state may be inconsistent. Don't worry, APISIX
will retry.
+
+Then we request: curl 127.0.0.1:9080/get
+
+We can see that the interface returns hello and does not access anything
upstream.
+
+### Setting up APISIX (running)
+
+Here's an example of go-runner, you just need to configure the command line to
run it inside ext-plugin:
+
+```
+ext-plugin:
+ # path_for_test: /tmp/runner.sock
+ cmd: ["/path/to/apisix-go-plugin-runner/go-runner", "run"]
+```
+
+APISIX will treat the plugin runner as a child process of its own, managing
its entire lifecycle.
+
+APISIX will automatically assign a unix socket address for the runner to
listen to when it starts. environment variables do not need to be set manually.