Restate is a system for easily building resilient applications using distributed durable async/await. This repository contains the Restate SDK for writing services using Rust.
- π€οΈ Join our online community for help, sharing feedback and talking to the community.
- π Check out our documentation to get quickly started!
- π£ Follow us on Twitter for staying up to date.
- π Create a GitHub issue for requesting a new feature or reporting a problem.
- π Visit our GitHub org for exploring other repositories.
Add Restate and Tokio as dependencies:
[dependencies]
restate-sdk = "0.1"
tokio = { version = "1", features = ["full"] }
Then you're ready to develop your Restate service using Rust:
use restate_sdk::prelude::*;
#[restate_sdk::service]
trait Greeter {
async fn greet(name: String) -> HandlerResult<String>;
}
struct GreeterImpl;
impl Greeter for GreeterImpl {
async fn greet(&self, _: Context<'_>, name: String) -> HandlerResult<String> {
Ok(format!("Greetings {name}"))
}
}
#[tokio::main]
async fn main() {
// To enable logging/tracing
// tracing_subscriber::fmt::init();
HttpServer::new(
Endpoint::builder()
.with_service(GreeterImpl.serve())
.build(),
)
.listen_and_serve("0.0.0.0:9080".parse().unwrap())
.await;
}
The Restate Rust SDK supports running services on AWS Lambda using Lambda Function URLs. This allows you to deploy your Restate services as serverless functions.
First, enable the lambda
feature in your Cargo.toml
:
[dependencies]
restate-sdk = { version = "0.1", features = ["lambda"] }
tokio = { version = "1", features = ["full"] }
Here's how to create a simple Lambda service:
use restate_sdk::prelude::*;
#[restate_sdk::service]
trait Greeter {
async fn greet(name: String) -> HandlerResult<String>;
}
struct GreeterImpl;
impl Greeter for GreeterImpl {
async fn greet(&self, _: Context<'_>, name: String) -> HandlerResult<String> {
Ok(format!("Greetings {name}"))
}
}
#[tokio::main]
async fn main() {
// To enable logging/tracing
// check https://docs.aws.amazon.com/lambda/latest/dg/rust-logging.html#rust-logging-tracing
// Build and run the Lambda endpoint
LambdaEndpoint::run(
Endpoint::builder()
.bind(GreeterImpl.serve())
.build(),
)
.await
.unwrap();
}
-
Install
cargo-lambda
cargo install cargo-lambda
-
Build your Lambda function:
cargo lambda build --release --arm64 --output-format zip
-
Create a Lambda function with the following configuration:
- Runtime: Amazon Linux 2023
- Architecture: arm64
-
Upload your
zip
file to the Lambda function.
The SDK uses tokio's tracing
crate to generate logs.
Just configure it as usual through tracing_subscriber
to get your logs.
The SDK uses Testcontainers to support integration testing using a Docker-deployed restate server.
The restate-sdk-testcontainers
crate provides a framework for initializing the test environment, and an integration test example in testcontainers/tests/test_container.rs
.
#[tokio::test]
async fn test_container() {
tracing_subscriber::fmt::fmt()
.with_max_level(tracing::Level::INFO) // Set the maximum log level
.init();
let endpoint = Endpoint::builder().bind(MyServiceImpl.serve()).build();
// simple test container intialization with default configuration
//let test_container = TestContainer::default().start(endpoint).await.unwrap();
// custom test container initialization with builder
let test_container = TestContainer::builder()
// optional passthrough logging from the resstate server testcontainer
// prints container logs to tracing::info level
.with_container_logging()
.with_container(
"docker.io/restatedev/restate".to_string(),
"latest".to_string(),
)
.build()
.start(endpoint)
.await
.unwrap();
let ingress_url = test_container.ingress_url();
// call container ingress url for /MyService/my_handler
let response = reqwest::Client::new()
.post(format!("{}/MyService/my_handler", ingress_url))
.header("Accept", "application/json")
.header("Content-Type", "*/*")
.header("idempotency-key", "abc")
.send()
.await
.unwrap();
assert_eq!(response.status(), StatusCode::OK);
info!(
"/MyService/my_handler response: {:?}",
response.text().await.unwrap()
);
}
The Rust SDK is currently in active development, and might break across releases.
The compatibility with Restate is described in the following table:
Restate Server\sdk-rust | 0.0 - 0.2 | 0.3 | 0.4 - 0.5 | 0.6 |
---|---|---|---|---|
1.0 | β | β | β | β |
1.1 | β | β | β | β |
1.2 | β | β | β | β |
1.3 | β | β | β | β (1) |
1.4 | β | β | β | β |
(1) Note bind_with_options
works only from Restate 1.4 onward.
Weβre excited if you join the Restate community and start contributing! Whether it is feature requests, bug reports, ideas & feedback or PRs, we appreciate any and all contributions. We know that your time is precious and, therefore, deeply value any effort to contribute!
Prerequisites:
To build and test the SDK:
just verify
You need the Rust toolchain. To verify:
just verify
To release we use cargo-release:
cargo release <VERSION> --exclude test-services --workspace