shreemaan-abhishek commented on code in PR #1627:
URL: https://github.com/apache/apisix-website/pull/1627#discussion_r1244609599


##########
blog/en/blog/2023/07/07/tiny-apisix-plugin.md:
##########
@@ -0,0 +1,203 @@
+---
+title: "A \"Tiny\" APISIX Plugin"
+authors:
+  - name: Navendu Pottekkat
+    title: Author
+    url: https://github.com/navendu-pottekkat
+    image_url: https://avatars.githubusercontent.com/u/49474499
+keywords:
+  - Wasm
+  - Go
+  - Plugin
+description: "A \"tiny\" example to demonstrate how Apache APISIX supports 
Wasm plugins."
+tags: [Plugins]
+image: https://static.apiseven.com/uploads/2023/06/27/Z8CkI8kj_wasm-cover.png
+---
+
+> In this article, we will write a "tiny" Go plugin for APISIX, compile it to 
a Wasm binary, run it in APISIX, and learn how it all works. We will also 
compare the benefits and costs of using Wasm plugins, external plugins (plugin 
runners), and native Lua plugins.
+
+<!--truncate-->
+
+A key feature of Apache APISIX is its pluggable architecture. In addition to 
providing [80+ Lua plugins](https://apisix.apache.org/plugins/) out of the box, 
APISIX also supports external plugins written in other languages through 
[plugin 
runners](https://apisix.apache.org/docs/go-plugin-runner/getting-started/) and 
[WebAssembly (Wasm)](https://apisix.apache.org/docs/apisix/next/wasm/).

Review Comment:
   > https://apisix.apache.org/docs/apisix/next/wasm/
   
   Don't you think it would be better to use 
"https://apisix.apache.org/docs/apisix/wasm/";? Because the current hyperlink is 
for the "next" version.



##########
blog/en/blog/2023/07/07/tiny-apisix-plugin.md:
##########
@@ -0,0 +1,203 @@
+---
+title: "A \"Tiny\" APISIX Plugin"
+authors:
+  - name: Navendu Pottekkat
+    title: Author
+    url: https://github.com/navendu-pottekkat
+    image_url: https://avatars.githubusercontent.com/u/49474499
+keywords:
+  - Wasm
+  - Go
+  - Plugin
+description: "A \"tiny\" example to demonstrate how Apache APISIX supports 
Wasm plugins."
+tags: [Plugins]
+image: https://static.apiseven.com/uploads/2023/06/27/Z8CkI8kj_wasm-cover.png
+---
+
+> In this article, we will write a "tiny" Go plugin for APISIX, compile it to 
a Wasm binary, run it in APISIX, and learn how it all works. We will also 
compare the benefits and costs of using Wasm plugins, external plugins (plugin 
runners), and native Lua plugins.
+
+<!--truncate-->
+
+A key feature of Apache APISIX is its pluggable architecture. In addition to 
providing [80+ Lua plugins](https://apisix.apache.org/plugins/) out of the box, 
APISIX also supports external plugins written in other languages through 
[plugin 
runners](https://apisix.apache.org/docs/go-plugin-runner/getting-started/) and 
[WebAssembly (Wasm)](https://apisix.apache.org/docs/apisix/next/wasm/).
+
+In this article, we will write a "tiny" Go plugin for APISIX, compile it to a 
Wasm binary, run it in APISIX, and learn how it all works. We will also compare 
the benefits and costs of using Wasm plugins, external plugins (plugin 
runners), and native Lua plugins.
+
+## APISIX and Wasm
+
+APISIX supports Wasm through the [WebAssembly for Proxies (proxy-wasm) 
specification](https://github.com/proxy-wasm/spec). APISIX is a host 
environment that implements the specification, and developers can use the 
[SDKs](https://github.com/proxy-wasm/spec#sdks) available in multiple languages 
to create plugins.
+
+Using Wasm plugins in APISIX has multiple advantages:
+
+* Many programming languages compile to Wasm. This allows you to leverage the 
capabilities of your tech stack in APISIX plugins.
+* The plugins run inside APISIX and not on external plugin runners. This means 
you compromise less on performance while writing external plugins.
+* Wasm plugins run inside APISIX but in a separate VM. So even if the plugin 
crashes, APISIX can continue to run.
+* _APISIX can only maintain its Wasm support without having to maintain plugin 
runners for multiple languages\*._
+
+_\* These advantages come with a set of caveats which we will look at later._
+
+APISIX's plugin architecture below shows native Lua plugins, external plugins 
through plugin runners, and Wasm plugins:
+
+![Lua plugins, plugin runners, and Wasm 
plugins](https://static.apiseven.com/uploads/2023/06/27/yBnZnCrv_plugin-route-light.png)
+
+## A "Tiny" Go Plugin
+
+Let's get coding! To write a Go plugin, we will use the 
[proxy-wasm-go-sdk](https://github.com/tetratelabs/proxy-wasm-go-sdk).
+
+Reading through the documentation, you will understand why this plugin is 
called "tiny," i.e., the SDK uses the [TinyGo](https://tinygo.org/) compiler 
instead of the official Go compiler. You can read more about why this is the 
case on the [SDK\'s overview 
page](https://github.com/tetratelabs/proxy-wasm-go-sdk/blob/main/doc/OVERVIEW.md),
 but the TLDR version is that the Go compiler can only produce Wasm binaries 
that run in the browser.
+
+For our example, we will create a plugin that adds a response header. The code 
below is pretty self-explanatory, and you can refer to [other 
plugins](https://github.com/apache/apisix/blob/master/t/wasm/) for more 
implementation details:
+
+```go title="main.go"
+// references:
+// https://github.com/tetratelabs/proxy-wasm-go-sdk/tree/main/examples
+// https://github.com/apache/apisix/blob/master/t/wasm/
+package main
+
+import (
+    "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm"
+    "github.com/tetratelabs/proxy-wasm-go-sdk/proxywasm/types"
+
+    "github.com/valyala/fastjson"
+)
+
+func main() {
+    proxywasm.SetVMContext(&vmContext{})
+}
+
+// each plugin has its own VMContext.
+// it is responsible for creating multiple PluginContexts for each route.
+type vmContext struct {
+    types.DefaultVMContext
+}
+
+// each route has its own PluginContext.
+// it corresponds to one instance of the plugin.
+func (*vmContext) NewPluginContext(contextID uint32) types.PluginContext {
+    return &pluginContext{}
+}
+
+type header struct {
+    Name  string
+    Value string
+}
+
+type pluginContext struct {
+    types.DefaultPluginContext
+    Headers []header
+}
+
+func (ctx *pluginContext) OnPluginStart(pluginConfigurationSize int) 
types.OnPluginStartStatus {
+    data, err := proxywasm.GetPluginConfiguration()
+    if err != nil {
+        proxywasm.LogErrorf("error reading plugin configuration: %v", err)
+        return types.OnPluginStartStatusFailed
+    }
+
+    var p fastjson.Parser
+    v, err := p.ParseBytes(data)
+    if err != nil {
+        proxywasm.LogErrorf("error decoding plugin configuration: %v", err)
+        return types.OnPluginStartStatusFailed
+    }
+    headers := v.GetArray("headers")
+    ctx.Headers = make([]header, len(headers))
+    for i, hdr := range headers {
+        ctx.Headers[i] = header{
+            Name:  string(hdr.GetStringBytes("name")),
+            Value: string(hdr.GetStringBytes("value")),
+        }
+    }
+    return types.OnPluginStartStatusOK
+}
+
+// each HTTP request to a route has its own HTTPContext
+func (ctx *pluginContext) NewHttpContext(contextID uint32) types.HttpContext {
+    return &httpContext{parent: ctx}
+}
+
+type httpContext struct {
+    types.DefaultHttpContext
+    parent *pluginContext
+}
+
+func (ctx *httpContext) OnHttpResponseHeaders(numHeaders int, endOfStream 
bool) types.Action {
+    plugin := ctx.parent
+    for _, hdr := range plugin.Headers {
+        proxywasm.ReplaceHttpResponseHeader(hdr.Name, hdr.Value)
+    }
+
+    return types.ActionContinue
+}
+```
+
+To compile our plugin to a Wasm binary, we can run:
+
+```shell
+tinygo build -o custom_response_header.go.wasm -scheduler=none -target=wasi 
./main.go
+```
+
+## Configuring APISIX to Run the Plugin
+
+To use the Wasm plugin, we first have to update our APISIX configuration file 
to add this:
+
+```yaml title="config.yaml"
+wasm:
+  plugins:
+    - name: custom-response-header
+      priority: 7000
+      file: /opt/apisix/wasm/custom_response_header.go.wasm
+```
+
+Now we can create a route and enable this plugin:

Review Comment:
   If a new user comes to this blog, they won't know that the following yaml 
configuration requires APISIX to be running on standalone mode. A little 
description about getting started with APISIX or a prerequisite list or a 
hyperlink to all necessary resources would be very neat.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to