WASM for microservices

In this blog post, I will share with you my experience of trying to use WebAssembly (Wasm) for building microservices. Wasm is a new technology that allows you to run compiled code in a browser or on a server. It promises to be faster, safer and more portable than traditional languages. However, as I learned the hard way, Wasm is not yet ready for prime time when it comes to microservices.

My project was inspired by a talk I attended at the Open Source Summit North America, where Kingdon Barrett of Weaveworks and Will Christensen of Defense Unicorns presented their findings on using Wasm for microservices. They had spent about three weeks exploring this topic and came up with a simple prototype that failed to meet their expectations. They also shared some of the challenges and limitations they faced with Wasm, such as:

– **No direct access to the network, file system or strings.**
– **No standard way to communicate with other services or external APIs.**
– **No mature tools or frameworks for developing and deploying Wasm microservices.**

I was intrigued by their talk and decided to give it a try myself. I wanted to see if I could overcome some of the obstacles they encountered and build a working microservice using Wasm. I chose Rust as my programming language, since it has good support for compiling to Wasm and is designed for performance and reliability. I also used WASI (WebAssembly System Interface) and WAGI (WebAssembly Gateway Interface) as the runtime environments for my microservice. WASI provides a set of system calls that Wasm modules can use, such as reading and writing files or opening sockets. WAGI allows Wasm modules to handle HTTP requests and responses using standard input and output.

My goal was to create a simple microservice that would take a text input from the user and return a summary of it using an external API. I thought this would be a good use case for Wasm, since it involves some computation and data processing that could benefit from the speed and safety of Wasm. I also wanted to test how easy or hard it would be to integrate with an existing service using Wasm.

The first challenge I faced was how to pass a string as an argument to my microservice. As Barrett and Christensen pointed out, there is no string type in Wasm. Instead, you have to manually allocate memory and copy bytes from one place to another. This is not only tedious but also error-prone. Fortunately, there are some libraries that can help with this task, such as wasm-bindgen for Rust. This library allows you to use Rust types like strings or vectors in your Wasm code and automatically handles the memory management for you.

The next challenge was how to make an HTTP request to the external API from my microservice. Since Wasm does not have direct access to the network, I had to use WASI’s socket functions to create a TCP connection and send and receive data over it. This was not too difficult, but it required me to write some low-level code that dealt with byte arrays, network protocols and error handling. It would have been much easier if I could use a high-level library like reqwest or curl for Rust, but unfortunately they do not work with Wasm yet.

The final challenge was how to deploy my microservice and make it accessible from the web. I used WAGI as the gateway for my microservice, which allowed me to run it as a standalone executable on any platform that supports WASI. However, WAGI is still very experimental and lacks some features that are essential for production use, such as logging, monitoring or authentication. Moreover, WAGI does not support HTTPS or load balancing, which means that I had to use another layer of proxy or service mesh to expose my microservice securely and reliably.

After spending several hours coding, debugging and testing, I managed to get my microservice working. It was able to take a text input from the user and return a summary of it using an external API. However, I was not very satisfied with the result. The code was complex, verbose and fragile. The performance was not impressive either. The microservice took about 300 milliseconds to respond on average, which is not much faster than a typical Node.js or Python service. The deployment process was also cumbersome and insecure.

In conclusion, I learned that Wasm is not yet ready for microservices. It has some potential advantages over traditional languages, such as speed, safety and portability, but it also has many drawbacks and limitations that make it unsuitable for real-world scenarios. It lacks standardization, maturity and ecosystem support that are essential for developing and deploying microservices effectively. It may improve in the future as more tools and frameworks emerge around it, but for now I would not recommend using it for microservices.