Develop APISIX plugin via Golang
APISIX allows users to extend functions through plugins, Although the Apache APISIX kernel code is written in Lua by the plugin, Apache APISIX supports the development of plugins in multiple languages, such as Go and Java. This article will explain in detail how to use plugins to develop Apache APISIX.
We will write an HTTP base auth plugin in Golang
write the plugin
Prerequisites
- Go (>= 1.15)
- apisix-go-plugin-runner
Let’s look at the Plugin interface, To write a custom plugin, we need to implement the plugin’s interface
1 | type Plugin interface { |
- Name returns the plugin’s name
- ParseConfig will accept a bytes array and we can define our plugin settings
- Filter that’s the place we handle HTTP request and response
Let’s start writing a plugin by Golang, in this example, we’ll write a basic-auth plugin, Basic Authentication is a method for an HTTP user agent (e.g., a web browser) to provide a username and password when making a request. When employing Basic Authentication, users include an encoded string in the Authorization header of each request they make.
The Authorization header follows this format:Authorization: Basic <credentials>
We then construct the credentials like this:
- The user’s username and password are combined with a colon.
- The resulting string is base64 encoded.
we’ll implement this plugin in the following ways.
- The plugins’ name will be
go-plugin-basic-auth
- Define the plugin’s config by username/password
- Handler HTTP request from Filter function, try to decode the Authorization and compare with the config, if the username/password matches, let the request go through (do nothing) otherwise return 401
Here’s the code
1 | type BasicAuthPlugin struct { |
And then register the plugin in the main function
1 | func main() { |
Run it
1 | APISIX_LISTEN_ADDRESS=unix:/tmp/runner.sock go run main.go |
After it starts, we’ll see logs like this
1 | 2022-03-07T19:43:41.952+0800 INFO plugin/plugin.go:66 register plugin go-plugin-basic-auth |
Now we can get into the next part
Integrations with APISIX
Run APISIX
The easy way to start apisix is to use docker, Here’s the example docker-compose file
1 | version: '3' |
and here’s the config file config.yaml
1 | apisix: |
we define the plugin’s listening sock in path_for_test
, That
means after hitting a routing rule, APISIX will make an RPC request to /tmp/runner.sock
.
run docker-compose up
to start apisix, use commands below to see if it workscurl "http://127.0.0.1:9080/apisix/admin/services/" -H 'X-API-KEY: edd1c9f034335f136f87ad84b625c8f1'
The following data is returned to indicate that Apache APISIX was successfully started:{ "count":1, "action":"get", "node":{ "key":"/apisix/services", "nodes":{}, "dir":true } }
Test the plugin
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.
create test routes with upstream and enable the plugin
1 | curl --location --request PUT 'http://127.0.0.1:9080/apisix/admin/routes/1' \ |
In this route, we set the following config
- define router in
/get
, APISIX will pass the request to its upstream httpbin.org - enable ext-plugin-pre-req plugin, add
go-plugin-basic-auth
and its config with thevalue
. username foo and password as bar
There are two kinds of plugins
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)
we use ext-plugin-pre-req for the base auth plugin because we need to break the request when the Authorization fails, and in the plugin config, we pass username and password AS JSON string which matches The Golang code BasicAuthConf
‘s structure.
Now let’s go to http://127.0.0.1:9080/get, the web browser will ask us to input username and password, fill the form with foo and bar then we’ll see the response from httpbin.org
Let’s it, develop Golang plugin in APISIX is easy
summary
At present, go plugin runner is still in the early development stage, and we will gradually improve its functions. A successful open source project is inseparable from your contributions. Welcome to participate in the development of the APISIX Go plugin runner. Let’s build a bridge between Apache APISIX and Go!
Full code repo
github.com:ezioruan/apisix_go_plugin_example
Related reading
https://apisix.apache.org/docs/go-plugin-runner/getting-started/