WebAssembly (abbreviated to Wasm) has a lot to offer the world of web applications. In the browser, it provides a secure, sandboxed execution environment that enables frontend developers to work in a variety of high-level languages (not just JavaScript!) without compromising on performance. And at the backend (server-side), WebAssembly’s cross-platform support and multi-architecture portability promise to make development, deployment, and scalability easier than ever.
At NGINX, we envision a world where you can create a server-side WebAssembly module and run it anywhere – without modification and without multiple build pipelines. Instead, your WebAssembly module would start at local development and run all the way to mission-critical, multi-cloud environments.
With the release of NGINX Unit 1.31, we’re excited to deliver on this vision. NGINX Unit is a universal web app server where application code is executed alongside the other essential attributes of TLS, static files, and request routing. Moreover, NGINX Unit does all of this while providing a consistent developer experience for seven programming language runtimes, and now also WebAssembly.
Adding WebAssembly to NGINX Unit makes sense on many levels:
Note: At the time of this writing, WebAssembly module is a Technology Preview – more details below.
NGINX Unit’s architecture decouples networking protocols from the application runtime. The unitd: router
process handles the incoming HTTP request, taking care of the TLS layer as required. After deciding what to do with this request, the “HTTP context” (URI, headers, and body) is then passed to the application runtime.
Many programming languages have a precise specification for how the HTTP context is made available to the application code, and how a developer can access URI, headers, and body. NGINX Unit provides several language modules that implement an interface layer between NGINX Unit’s router and the application runtime.
The WebAssembly language module for NGINX Unit provides a similar interface layer between the WebAssembly runtime and the router process. The WebAssembly sandbox’s linear memory is initialized with the HTTP context of the current request and the finalized response is sent back to the router for transmission to the client.
The sandboxed execution environment is provided by the Wasmtime runtime. The diagram below illustrates the flow of an HTTP request from client, through the router, to the WebAssembly module executed by Wasmtime.
Configuring NGINX Unit to execute a WebAssembly module is as straightforward as for any other language. In the configuration snippet below, there is an application called helloworld
with these attributes:
type
defines the language module to be loaded for this applicationmodule
points to a compiled WebAssembly bytecodeaccess
is a feature of the Wasmtime runtime that enables the application to access resources outside of the sandboxrequest_handler
, malloc_handler
, and free_handler
relate to the SDK functions that transfer the HTTP context to Wasmtime (more on that in the next section)
{
"applications":{
"helloworld":{
"type":"wasm",
"module":"/path/to/wasm_module.wasm",
"access":{
"filesystem":[
"/tmp",
"/var/tmp"
]
},
"request_handler":"luw_request_handler",
"malloc_handler":"luw_malloc_handler",
"free_handler":"luw_free_handler"
}
}
}
As mentioned above, NGINX Unit’s WebAssembly language module initializes the WebAssembly execution sandbox with the HTTP context of the current request. Where many programming language runtimes would provide native, direct access to the HTTP metadata, no such standard exists for WebAssembly.
We expect the WASI-HTTP standard to ultimately satisfy this need but, in the meantime, we provide a software development kit (SDK) for Rust and C. The Unit-Wasm SDK makes it easy to write web applications and APIs that compile to WebAssembly and run on NGINX Unit. In our how-to guide for WebAssembly, you can explore the development environment and build steps.
Despite our vision and desire to realize WebAssembly’s potential as a universal runtime, applications built with this SDK will only run on NGINX Unit. This is why we introduce WebAssembly support as a Technology Preview – we expect to replace it with WASI-HTTP support as soon as that is possible.
The Technology Preview is here to showcase the potential for server-side WebAssembly while providing a lightweight server for running web applications. Please approach it with a “kick the tires” mindset – experiment with it and provide us with feedback. We’d love to hear from you on the NGINX Community Slack or through the NGINX Unit GitHub repo.
To get started, install NGINX Unit and jump to the how-to guide for WebAssembly
"This blog post may reference products that are no longer available and/or no longer supported. For the most current information about available F5 NGINX products and solutions, explore our NGINX product family. NGINX is now part of F5. All previous NGINX.com links will redirect to similar NGINX content on F5.com."