|
| 1 | +:orphan: |
| 2 | + |
| 3 | +############################################################ |
| 4 | +WebAssembly Components with Fermyons Spin SDK for Rust |
| 5 | +############################################################ |
| 6 | + |
| 7 | +In our blog series `Part 1 </news/2024/wasm-component-model-part-1/>`__ and `2 </news/2024/wasm-component-model-part-2/>`__ we have covered the core mechanism of the |
| 8 | +WebAssembly Component Model and show cased how to create a Wasm Component using WASI 0.2 APIs and the **wasi/http:proxy** world. |
| 9 | + |
| 10 | +In this blog post, we will have a look on the `Fermyon's Spin <https://www.fermyon.com/spin>`__ SDK for `Rust <https://fermyon.github.io/rust-docs/spin/main/spin_sdk/index.html>`__ and create a component that can be hosted on NGINX Unit. |
| 11 | + |
| 12 | +The Spin SDK for Rust comes with a great developer experience as it wraps a lot of the manual work in an easy to consume Rust API. |
| 13 | + |
| 14 | +Let's start by creating a new Rust library using **cargo new**. This will create a new library project in a sub-directory **test-spin-component** of our current work directory. |
| 15 | + |
| 16 | + |
| 17 | +.. code-block:: bash |
| 18 | +
|
| 19 | + $ cargo new --lib test-spin-component |
| 20 | + $ cd test-spin-component |
| 21 | +
|
| 22 | +Add the latest version of the "spin-sdk" and "anyhow" (Flexible Error Types and a dependency of the Spin SDK) crates to the project by issuing: |
| 23 | + |
| 24 | +.. code-block:: bash |
| 25 | +
|
| 26 | + $ cargo add spin-sdk anyhow |
| 27 | +
|
| 28 | +Before we implement the actual functionality, we must modify our **Cargo.toml** file. Open the **Cargo.toml** with an editor of your |
| 29 | +choice and append the following to the bottom of your existing **Cargo.toml** file. |
| 30 | + |
| 31 | +.. code-block:: toml |
| 32 | +
|
| 33 | + [lib] |
| 34 | + crate-type = ["cdylib"] |
| 35 | +
|
| 36 | + [package.metadata.component] |
| 37 | + package = "component:test-component" |
| 38 | + proxy = true |
| 39 | +
|
| 40 | + [package.metadata.component.dependencies] |
| 41 | +
|
| 42 | +Next, replace the content of **src/lib.rs** file with the following code: |
| 43 | + |
| 44 | +.. code-block:: rust |
| 45 | +
|
| 46 | + use spin_sdk::http::{IntoResponse, Request, Response}; |
| 47 | + use spin_sdk::http_component; |
| 48 | +
|
| 49 | + #[http_component] |
| 50 | + fn handle_hello_world(_req: Request) -> anyhow::Result<impl IntoResponse> { |
| 51 | + let body_string = String::from("Hello, this is a Wasm Component using Spin SDK"); |
| 52 | +
|
| 53 | + Ok(Response::builder() |
| 54 | + .status(200) |
| 55 | + .header("Content-Type", "text/plain") |
| 56 | + .header("Content-Lenght", body_string.len().to_string()) |
| 57 | + .body(body_string) |
| 58 | + .build()) |
| 59 | + } |
| 60 | +
|
| 61 | +Compile the Rust Library into a Wasm Component using **cargo component**: |
| 62 | + |
| 63 | +.. code-block:: bash |
| 64 | +
|
| 65 | + $ cargo component build --release |
| 66 | +
|
| 67 | +To run the Wasm Component on NGINX Unit, startup Unit and use this initial configuration. |
| 68 | + |
| 69 | +.. note:: Make sure you point to the Wasm component by using an absolute path. |
| 70 | + |
| 71 | +.. code-block:: json |
| 72 | +
|
| 73 | + { |
| 74 | + "listeners": { |
| 75 | + "127.0.0.1:8085": { |
| 76 | + "pass": "applications/my-spin-component" |
| 77 | + } |
| 78 | + }, |
| 79 | + "applications": { |
| 80 | + "my-spin-component": { |
| 81 | + "type": "wasm-wasi-component", |
| 82 | + "component": "target/wasm32-wasi/release/test_spin_component.wasm" |
| 83 | + } |
| 84 | + } |
| 85 | + } |
| 86 | +
|
| 87 | +As the Wasm Component we have just crated uses the request and response interfaces defined by the **wasi:http/proxy** |
| 88 | +it can easily be deployed on NGINX Unit. |
0 commit comments