Skip to content

A template project to demonstrate how to run WebAssembly functions as sidecar microservices in dapr

License

Notifications You must be signed in to change notification settings

second-state/dapr-wasm

Repository files navigation

Dapr and WasmEdge

Tutorial video

Introduction

This is a template application to showcase how Dapr and WasmEdge work together to support lightweight WebAssembly-based microservices in a cloud-native environment. The microservices are all written in Rust and compiled into WebAssembly. They run inside the WasmEdge Runtime as opposed to Linux containers or VMs for these reasons.

While this demo is done in Rust, WasmEdge can also run Node.js compatible JavaScript applications.

This application consists of 3 microservices and a standalone web page that enables users to interact with the microservices using a HTML+JavaScript UI. It is a very typical JAMstack setup. Each microservice is attached to a Dapr sidecar, which provides a suite of useful services commonly required by cloud-native microservices. The overall architecture is as follows.

Microservices architecture

The Rust version of Dapr SDK for WasmEdge is used to access Dapr sidecars from the microservice apps. Specifically, the grayscale microservice takes an image from an HTTP POST, turns it into grayscale, and returns the result image data in the HTTP response.

  • It uses Dapr to discover and invoke the events microservice to record every successful user request.
  • It also stores each user’s IP address and last timestamp data in its Dapr sidecar’s state database. That allows the service to rate limit users if needed.

The classify microservices takes an image from an HTTP POST, runs a Tensorflow model against it to classify the object on the image, and returns the result as a text label in the HTTP response. You can learn more about AI inference in Rust and WasmEdge here. It uses its own Dapr sidecar the same way as the grayscale microservice.

The events microservice takes JSON data from a HTTP POST and saves it to an external MySQL database for later analysis.

  • It uses Dapr to make itself discoverable by name by other microservices that need to record events.
  • It also uses its Dapr sidecar to store secrets such as the MySQL database credentials.

Now, go ahead and fork this repo. Create and deploy your own lightweight microservices for better security, faster performance, and smaller footprints.

Build and deploy these microservices in Dapr

You will need install the following software toolchain to run these examples. The detailed steps are shown in the GitHub Actions script.

Start the database and place the connection string in the config/secrets.json file under DB_URL:MYSQL. Next, start Dapr with the following commands.

dapr init

The image grayscale microservice

Build.

cd image-api-grayscale
cargo build --target wasm32-wasi --release
wasmedge compile ./target/wasm32-wasi/release/image-api-grayscale.wasm image-api-grayscale.wasm

Deploy.

dapr run --app-id image-api-grayscale \
        --app-protocol http \
        --app-port 9005 \
        --dapr-http-port 3503 \
        --components-path ../config \
        --log-level debug \
	wasmedge image-api-grayscale.wasm

The image classification microservice

Build.

cd image-api-classify
cargo build --target wasm32-wasi --release
wasmedge compile target/wasm32-wasi/release/wasmedge_hyper_server_tflite.wasm wasmedge_hyper_server_tflite.wasm

Deploy.

dapr run --app-id image-api-classify \
        --app-protocol http \
        --app-port 9006 \
        --dapr-http-port 3504 \
        --log-level debug \
        --components-path ../config \
        wasmedge wasmedge_hyper_server_tflite.wasm

The events recorder microservice

Build.

cd events-service
cargo build --target wasm32-wasi --release
wasmedge compile target/wasm32-wasi/release/events_service.wasm events_service.wasm

Deploy.

dapr run --app-id events-service \
        --app-protocol http \
        --app-port 9007 \
        --dapr-http-port 3505 \
        --log-level debug \
        --components-path ../config \
        wasmedge events_service.wasm

Test

You can use the static web page UI or curl to test the services.

Initialize the events database table.

$ curl http://localhost:9007/init
{"status":true}

$ curl http://localhost:9007/events
[]

Use the grayscale microservice. The return data is base64 encoded grayscale image.

$ cd docs
$ curl http://localhost:9005/grayscale -X POST --data-binary '@food.jpg'
ABCDEFG ...

Use the image classification microservice.

$ cd docs
$ curl http://localhost:9006/classify -X POST --data-binary '@food.jpg'
hotdog is detected with 255/255 confidence

Query the events database again.

$ curl http://localhost:9007/events
[{"id":1,"event_ts":1665358852918,"op_type":"grayscale","input_size":68016},{"id":2,"event_ts":1665358853114,"op_type":"classify","input_size":68016}]

Learn more

About

A template project to demonstrate how to run WebAssembly functions as sidecar microservices in dapr

Topics

Resources

License

Stars

Watchers

Forks

Languages