(Dec. 9th 2024) Flawless Beta 3 is here. Try it out!
  Flawless Logo, a beautiful woman with freckles head illustration. flawless.dev docs replay discord

Fundamentals

Workflows in Flawless are just regular Rust functions annotated with the #[workflow("<name>")] macro.

#[workflow("test")]
fn workflow() {
    info!("Hello from workflow!");
}

Input arguments

Workflows can also take one input argument.

use flawless::{workflow, workflow::Input};
use log::info;

flawless::module! { name = "test", version = "0.0.1" }

#[workflow("test")]
fn test(name: Input<String>) {
    info!("Hello {}!", *name);
}

Running it with:

$ flawless deploy
$ flawless run test:0.0.1 test --input '"World"'

will print out something like:

[2024-10-03T19:47:25Z INFO] Hello World!

The input can be any structure that implements the serde::Deserialize trait. And it's passed to the workflow as a JSON value. In this example the input is a JSON string ("World").

Response

A workflow can also return a response.

use flawless::{workflow, workflow::Response};

flawless::module! { name = "response", version = "0.0.1" }

#[workflow("test")]
fn test(response: Response) {
    response.send("This is a response").unwrap();
}

Run it!

$ flawless deploy
$ flawless run response:0.0.1 test

> Workflow with ID 'wkf_mVH3f' started.
> Response: This is a response

Responses are taken as a first argument, so that they can be sent at any point back. The HTTP API will block until a response is sent back. For workflows that don't take a Response argument, the response is sent right away and is empty.

Messages

Workflows can wait for external messages.

use flawless::{message, message::receive, workflow};

flawless::module! { name = "msg", version = "0.0.1" }

#[workflow("test")]
fn test() {
    let msg: Msg = receive();
    log::info!("{} {}!", msg.greeting, msg.name);
}

#[message("msg")]
struct Msg {
    greeting: String,
    name: String,
}

Messages can be sent to the Flawless HTTP API in JSON format.

$ flawless deploy
$ flawless run msg:0.0.1 test 

> Workflow with ID 'wkf_mVH3f' started.

Now use curl to send a JSON encoded message with the correct type to the workflow.

$ curl --header "Content-Type: application/json" \
    --request POST \
    --data '{"type":"greeting_msg", "data":"{\"greeting\":\"hello\",\"name\":\"flawless\"}"}' \
    http://localhost:27288/api/workflow/send-msg/wkf_mVH3f

> "ok"

This will log the following line on the server:

[2024-10-10T05:16:31Z INFO] hello flawless!

Notice that the data field value is escaped, as it takes a JSON encoded string.

Working with secrets

Secrets are variables that you can set with:

$ flawless secret add <VARIABLE> <VALUE>

Inside the workflows, you can retrieve a secret using the secret::get() function.

let secret = flawless::secrets::get_secret("VARIABLE");