# Source: https://github.com/WasmEdge/docs.git
# Path: embed/use-case/wasm-nginx.md

---
sidebar_position: 3
---

# wasm-nginx-module

The wasm-nginx-module is an Nginx module built upon OpenResty. By implementing the [Proxy-WASM ABI](https://github.com/proxy-wasm/spec), any WASM program written with Proxy WASM SDK can be run inside it. Hence, you can write Go or Rust code, compile them into Wasm, then load & execute it in Nginx.

> The wasm-nginx-module is already used in APISIX and allows it to [run WASM plugin like Lua plugin](https://github.com/apache/apisix/blob/master/docs/en/latest/wasm.md).

To follow along the tutorials in this chapter, you will need to first [build your Nginx with wasm-nginx-module included and WasmEdge shared library installed in the right path](https://github.com/api7/wasm-nginx-module#install-dependencies).

Once you have Nginx installed, let me show you a real-world example - using WASM to inject custom responses in Nginx.

## Inject Custom Response via Go in Nginx, Step by Step

### Go Step 1: Write code based on proxy-wasm-go-sdk

The implementation code (including `go.mod` and others) can be found [here](https://github.com/apache/apisix/tree/master/t/wasm).

It should be explained that although the proxy-wasm-go-sdk project carries the Go name, it actually uses tinygo instead of native Go, which has some problems supporting WASI (which you can think of as a non-browser WASM runtime interface). See [here](https://github.com/tetratelabs/proxy-wasm-go-sdk/blob/main/doc/OVERVIEW.md#tinygo-vs-the-official-go-compiler) for more details.

We also provide a Rust version (including Cargo.toml and others) [there](https://github.com/api7/wasm-nginx-module/tree/main/t/testdata/rust/fault-injection).

### Go Step 2: Build the corresponding WASM file

```shell
tinygo build -o ./fault-injection/main.go.wasm -scheduler=none -target=wasi ./fault-injection/main.go
```

### Go Step 3: Load and execute the WASM file

Then, start Nginx with the configuration below:

```conf
worker_processes  1;

error_log  /tmp/error.log warn;

events {
    worker_connections  10240;
}

http {
    wasm_vm wasmedge;
    init_by_lua_block {
        local wasm = require("resty.proxy-wasm")
        package.loaded.plugin = assert(wasm.load("fault_injection",
            "/path/to/fault-injection/main.go.wasm"))
    }
    server {
        listen 1980;
        location / {
            content_by_lua_block {
                local wasm = require("resty.proxy-wasm")
                local ctx = assert(wasm.on_configure(package.loaded.plugin,
                    '{"http_status": 403, "body": "powered by wasm-nginx-module"}'))
                assert(wasm.on_http_request_headers(ctx))
            }
        }
    }
}
```

This configuration loads the WASM file we just built, and executes it with the configuration `{"http_status": 403, "body": "powered by wasm-nginx-module"}`.

### Go Step 4: Verify the Result

After Nginx starts, we can use `curl http://127.0.0.1:1980/ -i` to verify the execution result of the Wasm.

It is expected to see the output:

```bash
HTTP/1.1 403 Forbidden
...

powered by wasm-nginx-module
```

## Inject Custom Response via Rust in Nginx, Step by Step

### Rust Step 1: Write code based on proxy-wasm-rust-sdk

We also provide a Rust version (including Cargo.toml and others) [here](https://github.com/api7/wasm-nginx-module/tree/main/t/testdata/rust/fault-injection).

### Rust Step 2: Build the corresponding WASM file

```shell
cargo build --target=wasm32-wasip1
```

### Rust Step 3: Load and execute the WASM file

Then, start Nginx with the configuration below:

```conf
worker_processes  1;

error_log  /tmp/error.log warn;

events {
    worker_connections  10240;
}

http {
    wasm_vm wasmedge;
    init_by_lua_block {
        local wasm = require("resty.proxy-wasm")
        package.loaded.plugin = assert(wasm.load("fault_injection",
            "/path/to/fault-injection/target/wasm32-wasip1/debug/fault_injection.wasm"))
    }
    server {
        listen 1980;
        location / {
            content_by_lua_block {
                local wasm = require("resty.proxy-wasm")
                local ctx = assert(wasm.on_configure(package.loaded.plugin,
                    '{"http_status": 403, "body": "powered by wasm-nginx-module"}'))
                assert(wasm.on_http_request_headers(ctx))
            }
        }
    }
}
```

This configuration loads the WASM file we just built, executes it with the configuration `{"http_status": 403, "body": "powered by wasm-nginx-module"}`.

### Rust Step 4: verify the result

After Nginx starts, we can use `curl http://127.0.0.1:1980/ -i` to verify the execution result of the Wasm.

It is expected to see the output:

```bash
HTTP/1.1 403 Forbidden
...

powered by wasm-nginx-module
```