diff --git a/macros/src/lib.rs b/macros/src/lib.rs index 501273f..8290af3 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -22,7 +22,6 @@ use proc_macro::TokenStream; use quote::ToTokens; use syn::parse_macro_input; -/// Entry-point macro to define a Restate service. #[proc_macro_attribute] pub fn service(_: TokenStream, input: TokenStream) -> TokenStream { let svc = parse_macro_input!(input as Service); @@ -32,7 +31,6 @@ pub fn service(_: TokenStream, input: TokenStream) -> TokenStream { .into() } -/// Entry-point macro to define a Restate object. #[proc_macro_attribute] pub fn object(_: TokenStream, input: TokenStream) -> TokenStream { let svc = parse_macro_input!(input as Object); @@ -42,7 +40,6 @@ pub fn object(_: TokenStream, input: TokenStream) -> TokenStream { .into() } -/// Entry-point macro to define a Restate workflow. #[proc_macro_attribute] pub fn workflow(_: TokenStream, input: TokenStream) -> TokenStream { let svc = parse_macro_input!(input as Workflow); diff --git a/src/context/run.rs b/src/context/run.rs index bd83dcc..ee8ac53 100644 --- a/src/context/run.rs +++ b/src/context/run.rs @@ -25,7 +25,7 @@ where } } -/// Future created using [`super::ContextSideEffects::run`]. +/// Future created using [`ContextSideEffects::run`](super::ContextSideEffects::run). pub trait RunFuture: Future { /// Provide a custom retry policy for this `run` operation. /// diff --git a/src/endpoint/mod.rs b/src/endpoint/mod.rs index cc8176f..c539328 100644 --- a/src/endpoint/mod.rs +++ b/src/endpoint/mod.rs @@ -194,7 +194,8 @@ impl Builder { /// Add a [`Service`] to this endpoint. /// - /// When using the service/object/workflow macros, you need to pass the result of the `serve` method. + /// When using the [`service`](macro@crate::service), [`object`](macro@crate::object) or [`workflow`](macro@crate::workflow) macros, + /// you need to pass the result of the `serve` method. pub fn bind< S: Service>> + Discoverable diff --git a/src/lib.rs b/src/lib.rs index c677413..91b6bd0 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -48,7 +48,145 @@ pub mod http_server; pub mod hyper; pub mod serde; -pub use restate_sdk_macros::{object, service, workflow}; +/// Entry-point macro to define a Restate [Service](https://docs.restate.dev/concepts/services#services-1). +/// +/// ```rust,no_run +/// use restate_sdk::prelude::*; +/// +/// #[restate_sdk::service] +/// trait Greeter { +/// async fn greet(name: String) -> Result; +/// } +/// ``` +/// +/// This macro accepts a `trait` as input, and generates as output: +/// +/// * A trait with the same name, that you should implement on your own concrete type (e.g. `struct`), e.g.: +/// +/// ```rust,no_run +/// # use restate_sdk::prelude::*; +/// # #[restate_sdk::service] +/// # trait Greeter { +/// # async fn greet(name: String) -> Result; +/// # } +/// struct GreeterImpl; +/// impl Greeter for GreeterImpl { +/// async fn greet(&self, _: Context<'_>, name: String) -> Result { +/// Ok(format!("Greetings {name}")) +/// } +/// } +/// ``` +/// +/// This trait will additionally contain, for each handler, the appropriate [`Context`](crate::prelude::Context), to interact with Restate. +/// +/// * An implementation of the [`Service`](crate::service::Service) trait, to bind the service in the [`Endpoint`](crate::prelude::Endpoint) and expose it: +/// +/// ```rust,no_run +/// # use restate_sdk::prelude::*; +/// # #[restate_sdk::service] +/// # trait Greeter { +/// # async fn greet(name: String) -> HandlerResult; +/// # } +/// # struct GreeterImpl; +/// # impl Greeter for GreeterImpl { +/// # async fn greet(&self, _: Context<'_>, name: String) -> HandlerResult { +/// # Ok(format!("Greetings {name}")) +/// # } +/// # } +/// let endpoint = Endpoint::builder() +/// // .serve() returns the implementation of Service used by the SDK +/// // to bind your struct to the endpoint +/// .bind(GreeterImpl.serve()) +/// .build(); +/// ``` +/// +/// * A client implementation to call this service from another service, object or workflow, e.g.: +/// +/// ```rust,no_run +/// # use restate_sdk::prelude::*; +/// # #[restate_sdk::service] +/// # trait Greeter { +/// # async fn greet(name: String) -> HandlerResult; +/// # } +/// # async fn example(ctx: Context<'_>) -> Result<(), TerminalError> { +/// let result = ctx +/// .service_client::() +/// .greet("My greetings".to_string()) +/// .call() +/// .await?; +/// # Ok(()) +/// # } +/// ``` +/// +/// Methods of this trait can accept either no parameter, or one parameter implementing [`Deserialize`](crate::serde::Deserialize). +/// The return value MUST always be a `Result`. Down the hood, the error type is always converted to [`HandlerError`](crate::prelude::HandlerError) for the SDK to distinguish between terminal and retryable errors. For more details, check the [`HandlerError`](crate::prelude::HandlerError) doc. +/// +/// When invoking the service through Restate, the method name should be used as handler name, that is: +/// +/// ```rust,no_run +/// use restate_sdk::prelude::*; +/// +/// #[restate_sdk::service] +/// trait Greeter { +/// async fn my_greet(name: String) -> Result; +/// } +/// ``` +/// +/// The `Greeter/my_greet` handler be invoked sending a request to `http:///Greeter/my_greet`. +/// You can override the names used by Restate during registration using the `name` attribute: +/// +/// ```rust,no_run +/// use restate_sdk::prelude::*; +/// +/// #[restate_sdk::service] +/// #[name = "greeter"] +/// trait Greeter { +/// // You can invoke this handler with `http:///greeter/myGreet` +/// #[name = "myGreet"] +/// async fn my_greet(name: String) -> Result; +/// } +/// ``` +pub use restate_sdk_macros::service; + +/// Entry-point macro to define a Restate [Virtual object](https://docs.restate.dev/concepts/services#virtual-objects). +/// +/// For more details, check the [`service` macro](macro@crate::service) documentation. +/// +/// ## Shared handlers +/// +/// To define a shared handler, simply annotate the handler with the `#[shared]` annotation: +/// +/// ```rust,no_run +/// use restate_sdk::prelude::*; +/// +/// #[restate_sdk::object] +/// trait Counter { +/// async fn add(val: u64) -> Result; +/// #[shared] +/// async fn get() -> Result; +/// } +/// ``` +pub use restate_sdk_macros::object; + +/// Entry-point macro to define a Restate [Workflow](https://docs.restate.dev/concepts/services#workflows). +/// +/// For more details, check the [`service` macro](macro@crate::service) documentation. +/// +/// ## Shared handlers +/// +/// To define a shared handler, simply annotate the handler with the `#[shared]` annotation: +/// +/// ```rust,no_run +/// use restate_sdk::prelude::*; +/// +/// #[restate_sdk::workflow] +/// trait Billing { +/// async fn run() -> Result; +/// #[shared] +/// async fn get_status() -> Result; +/// } +/// ``` +pub use restate_sdk_macros::workflow; /// Prelude contains all the useful imports you need to get started with Restate. pub mod prelude {