Does the existence of WASI mean that I can also run Rust programs on Workers, compiled to WASM (without the JS shim)? Does anyone know of any tutorials on this? It would be great if I could access the Request object, with all the headers, payload, etc from Rust.
Yes, when they initially announced this feature, they actually demo'd running an unmodified Rust program compiled to wasm32-wasi. It just takes the HTTP body as stdin and writes the response from stdout, though, so it's limited: https://blog.cloudflare.com/announcing-wasi-on-workers/
I also did this recently but with the shim approach: a small Rust program that needs to run a cryptography operation on some input[1], compiled to wasi and operating on stdin/stdout, and then invoked by a larger Typescript program invoking it with the proper stream. Worked great.
There is also a thing called workers-rs[2] which will let you write the entire worker in Rust, but it does not use WASI. WASI isn't really enough for anything beyond simple stdin/stdout pipelines without something "wrapping it" to provide the needed fds, env vars, arguments, etc. So instead workers-rs binds to the underlying Worker runtime primitives, the ones normal JavaScript uses, and exposes that -- but it does all of the mangling/bindgen/shim bullshit for you in the background. The shim is unavoidable, and always exists behind the curtain, but this approach lets you completely ignore it. workers-rs doesn't support every API, though (e.g. no R2 support.) In theory, assuming you ported the workers-wasi interface to Rust[3] yourself, you could then write a Worker in Rust using workers-rs that load WASI-conformant WASM programs (written in XYZ) and execute that program on the request object. Sounds confusing but I think you get what I mean.
[1] No, this operation wasn't provided by the WebCrypto API, as far as I'm aware, otherwise I probably wouldn't have bothered with the added complexity.
[3] The underlying WebAssembly support comes from V8; WASI, then, is "just" an implementation of some very well known functions/APIs in the surrounding environment that the WASM program expects to exist, and behave in a certain way. So actually the entire workers-wasi framework is here, and if you ported this TypeScript interface to Rust, using workers-rs, you could invoke any WASI program similarly: https://github.com/cloudflare/workers-wasi/blob/main/src/ind...
I see, thanks! Sounds like WASI is pretty minimal, then, and we're basically going back to CGI, but it might be good enough. workers-rs looks interesting, though, thank you!
Technically it never went away! FastCGI is still plenty good enough for deploying lots of stuff with PHP. :) And I think the reason people like these new "serverless" things is exactly because, like CGI, it feels pretty developer oriented. Request goes in -- response comes out. Hard to beat that in a way. The no-management part is the real sell, though.
Yeah, that's kind of cheating... it runs Rust after compiling it to WASM and running that inside a JS runtime! Anyone thinking of using that should definitely consider just using WASI instead as Rust, as Zig, can compile to WASM/WASI (for those who don't know, WASI is like a POSIX for WASM, so WASM-compiled programs have access to a POSIX-like API, and therefore don't depend on the Web APIs like the Rust-compiled-to-worker solution does).