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 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-test-env
crate provides a framework for initializing the test environment, and an integration test example in test-env/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.1/0.2 | 0.3 |
---|---|---|
1.0 | ✅ | ❌ |
1.1 | ✅ | ✅ |
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