This sample demonstrates a web application with a WebAssembly (Wasm) microservice, written in Rust. The Wasm microservice is an HTTP API connected to a MySQL (MariaDB) database. The API is invoked via from JavaScript in a web interface serving static HTML. The microservice is compiled into WebAssembly (Wasm) and runs in the WasmEdge Runtime, a secure and lightweight alternative to natively compiled Rust apps in Linux containers. Checkout this article or this video to learn how the Rust code in this microservice works.
You will need a version of Docker Desktop or Docker CLI with Wasm support.
Project structure:
.
+-- compose.yml
|-- backend
+-- Dockerfile
|-- Cargo.toml
|-- src
+-- main.rs
|-- frontend
+-- index.html
|-- js
+-- app.js
|-- db
+-- orders.json
|-- update_order.json
The compose.yml file:
services:
frontend:
image: nginx:alpine
ports:
- 8090:80
volumes:
- ./frontend:/usr/share/nginx/html
backend:
image: demo-microservice
build:
context: backend/
platforms:
- wasi/wasm32
ports:
- 8080:8080
environment:
DATABASE_URL: mysql://root:whalehello@db:3306/mysql
RUST_BACKTRACE: full
restart: unless-stopped
runtime: io.containerd.wasmedge.v1
db:
image: mariadb:10.9
environment:
MYSQL_ROOT_PASSWORD: whalehello
The compose file defines an application with three services frontend
, backend
and db
. The frontend
is a simple Nginx server that hosts static web pages that access the backend
web service, in the WasmEdge container, via HTTP port 8080. When deploying the application, docker compose maps port 8090 of the frontend
service container to port 8090 of the host as specified in the file. Make sure that ports 8090 and 8080 on the host are not already being used.
$ docker compose up -d
...
⠿ Network wasmedge-mysql-nginx_default Created
⠿ Container wasmedge-mysql-nginx-db-1 Created
⠿ Container wasmedge-mysql-nginx-frontend-1 Created
⠿ Container wasmedge-mysql-nginx-backend-1 Created
$ docker compose ps
NAME COMMAND SERVICE STATUS PORTS
wasmedge-mysql-nginx-backend-1 "order_demo_service.…" backend running 0.0.0.0:8080->8080/tcp, :::8080->8080/tcp
wasmedge-mysql-nginx-db-1 "docker-entrypoint.s…" db running 3306/tcp
wasmedge-mysql-nginx-frontend-1 "/docker-entrypoint.…" frontend running 0.0.0.0:8090->80/tcp, :::8090->80/tcp
After the application starts, go to http://localhost:8090
in your web browser to display the web frontend.
As an alternative to the web frontend, you can use curl
to interact with the WasmEdge API directly (the backend
service).
When the WasmEdge web service receives a GET request to the /init
endpoint, it would initialize the database with the orders
table.
curl http://localhost:8080/init
When the WasmEdge web service receives a POST request to the /create_order
endpoint, it extracts the JSON data from the POST body and inserts an Order
record into the database table.
To insert multiple records, use the /create_orders
endpoint and POST a JSON array of Order
objects:
curl http://localhost:8080/create_orders -X POST -d @db/orders.json
When the WasmEdge web service receives a GET request to the /orders
endpoint, it gets all rows from the orders
table and return the result set in a JSON array in the HTTP response.
curl http://localhost:8080/orders
When the WasmEdge web service receives a POST request to the /update_order
endpoint, it extracts the JSON data from the POST body and update the Order
record in the database table that matches the order_id
in the input data.
curl http://localhost:8080/update_order -X POST -d @db/update_order.json
When the WasmEdge web service receives a GET request to the /delete_order
endpoint, it deletes the row in the orders
table that matches the id
GET parameter.
curl http://localhost:8080/delete_order?id=2