What's new in Wasm Workers Server v0.6.0

You can find above the video version of this article
The goal of Wasm Workers Server (wws
) is to simplify the development of worker-based applications and run them everywhere. Thanks to WebAssembly, you can do so using many different languages. If you haven't tried wws
yet, you can get started here 😊.
The recent v0.6.0 release includes several new features and fixes, with the following highlights:
- Added support for a static assets folder (#7)
- Added support for environment variables (#34)
- Fixed workers' URLs in Windows and Unix systems (#30)
We also introduced two breaking changes in v0.6.0. Even though we want to avoid them whenever possible, we may need to add more until we reach v1.0.0.
- Rename the Rust macro attribute to
worker
(#43) - Allow Rust workers to return different body types (#44)
To install wws
or update your current version, run the install.sh
script:
curl https://raw.githubusercontent.com/vmware-labs/wasm-workers-server/main/install.sh | bash
And now, let's dive into the details! 👇
Static assets folder
Static assets are part of any modern application. Most web apps require stylesheets (CSS), JavaScript (JS), images, and others files. Previously, the Wasm modules bundled these assets, making it difficult to update them and requiring the module to process the request rather than let the server itself return the assets directly.
In v0.6.0, we introduced the public
folder. To serve static assets in your application, create a public
folder at the root of your project. wws
will serve any file there as a static resource. The final asset URL will start from the root path. For example, public/robots.txt
will be accessible on /robots.txt
. Now, you can reference any of them in your workers' response.
Check our documentation for more information about static assets.
Environment variables
Environment variables is a common and convenient way to configure an application. Unlike other platforms, the WebAssembly runtime isolates the modules completely and by default they don't have access to any variable.
In v0.6.0, we added a new configuration parameter to inject environment variables in your worker. Every worker gets its own set of variables, to avoid accidentally leaking information or secrets to the wrong module.
To add a new environment variable to a worker, create an associated TOML
configuration file and set the [vars]
entry:
name = "json"
version = "1"
[vars]
JSON_MESSAGE = "Hello 👋! This message comes from an environment variable"
You can also pass an existing environment variable or rename it with the $
notation:
name = "json"
version = "1"
[vars]
TOKEN = "$TOKEN"
Check our documentation for more information about environment variables.
Rename the Rust macro attribute to worker
🚨 This feature introduces a breaking change for Rust workers. You will need to recompile them using the latest available version.
To keep a consistent naming, we updated the Rust kit macro attribute from handler
to worker
. It works the same way. You only need to update the macro import and its usage in your Rust workers:
use anyhow::Result;
use wasm_workers_rs::{
http::{self, Request, Response},
- handler, Content
+ worker, Content,
};
- #[handler]
+ #[worker]
fn handler(req: Request<String>) -> Result<Response<Content>> {
// ...
}
Allow Rust workers to return different body types
🚨 This feature introduces a breaking change for Rust workers. You will need to recompile them using the latest available version.
In the initial Rust worker kit, all worker function returned a String
as the body type. This assumption limited the use cases as binary responses cannot be encoded as a Rust String
.
In this new version, Rust workers return a custom type called Content
in the response body. It allows your workers to return a string or binary data to users. Content
will build the final response from a String
or a Vec<u8>
(array of bytes).
We created a pdf-create worker to showcase this feature.
use anyhow::Result;
use printpdf::*;
use std::io::BufWriter;
use wasm_workers_rs::{
http::{self, Request, Response},
worker, Content,
};
#[worker]
fn handler(req: Request<String>) -> Result<Response<Content>> {
let mut buf = BufWriter::new(Vec::new());
// ... PDF creation
let bytes = buf.into_inner()?;
Ok(http::Response::builder()
.status(200)
.header("Content-Disposition", "attachment; filename=\"quote.pdf\"")
.header("Content-Type", "application/pdf")
.header("x-generated-by", "wasm-workers-server")
.body(bytes.into())?)
}
For workers that return a String
, you still have to change the body type to Content
:
use anyhow::Result;
use wasm_workers_rs::{
http::{self, Request, Response},
worker, Content,
};
#[worker]
-fn handler(req: Request<String>) -> Result<Response<String>> {
+fn handler(req: Request<String>) -> Result<Response<Content>> {
let data = String::from("Hello Wasm!");
Ok(http::Response::builder()
.status(200)
.header("x-generated-by", "wasm-workers-server")
.body(data.into())?)
}
Fix workers' URLs in Windows and Unix systems
We want any developer to be able to use the same tools consistently, regardless of their OS environment. For this reason, we revisited the Windows support in v0.6.0
. We found several issues related to path management. Before, wws
didn't route workers inside a subfolder properly.
In v0.6.0, we fixed all these issues. Developers in Windows can now use wws
with a custom folder structure as Linux and macOS already do. We also introduced a new --prefix
option. It sets a prefix to all the URLs making it easy to serve URLs in a specific path:
$ wws --prefix=/app ./examples/js-basic/
⚙️ Loading routes from: ./examples/js-basic/
🗺 Detected routes:
- http://127.0.0.1:8080/app/handler
=> examples/js-basic/handler.js (handler: default)
🚀 Start serving requests at http://127.0.0.1:8080
v0.6.0
Finally, we want to thank all the contributors in v0.6.0 and v0.5.1. We are excited to see how developers started to create their initial workers and contributed back to wws
. Together, we are simplifying how to develop applications with Wasm!