restate_sdk/context/
request.rs

1use crate::endpoint::ContextInternal;
2use crate::errors::TerminalError;
3use crate::serde::{Deserialize, Serialize};
4use std::fmt;
5use std::future::Future;
6use std::marker::PhantomData;
7use std::time::Duration;
8
9/// Target of a request to a Restate service.
10#[derive(Debug, Clone)]
11pub enum RequestTarget {
12    Service {
13        name: String,
14        handler: String,
15    },
16    Object {
17        name: String,
18        key: String,
19        handler: String,
20    },
21    Workflow {
22        name: String,
23        key: String,
24        handler: String,
25    },
26}
27
28impl RequestTarget {
29    pub fn service(name: impl Into<String>, handler: impl Into<String>) -> Self {
30        Self::Service {
31            name: name.into(),
32            handler: handler.into(),
33        }
34    }
35
36    pub fn object(
37        name: impl Into<String>,
38        key: impl Into<String>,
39        handler: impl Into<String>,
40    ) -> Self {
41        Self::Object {
42            name: name.into(),
43            key: key.into(),
44            handler: handler.into(),
45        }
46    }
47
48    pub fn workflow(
49        name: impl Into<String>,
50        key: impl Into<String>,
51        handler: impl Into<String>,
52    ) -> Self {
53        Self::Workflow {
54            name: name.into(),
55            key: key.into(),
56            handler: handler.into(),
57        }
58    }
59}
60
61impl fmt::Display for RequestTarget {
62    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
63        match self {
64            RequestTarget::Service { name, handler } => write!(f, "{name}/{handler}"),
65            RequestTarget::Object { name, key, handler } => write!(f, "{name}/{key}/{handler}"),
66            RequestTarget::Workflow { name, key, handler } => write!(f, "{name}/{key}/{handler}"),
67        }
68    }
69}
70
71/// This struct encapsulates the parameters for a request to a service.
72pub struct Request<'a, Req, Res = ()> {
73    ctx: &'a ContextInternal,
74    request_target: RequestTarget,
75    req: Req,
76    res: PhantomData<Res>,
77}
78
79impl<'a, Req, Res> Request<'a, Req, Res> {
80    pub(crate) fn new(ctx: &'a ContextInternal, request_target: RequestTarget, req: Req) -> Self {
81        Self {
82            ctx,
83            request_target,
84            req,
85            res: PhantomData,
86        }
87    }
88
89    /// Call a service. This returns a future encapsulating the response.
90    pub fn call(self) -> impl Future<Output = Result<Res, TerminalError>> + Send
91    where
92        Req: Serialize + 'static,
93        Res: Deserialize + 'static,
94    {
95        self.ctx.call(self.request_target, self.req)
96    }
97
98    /// Send the request to the service, without waiting for the response.
99    pub fn send(self)
100    where
101        Req: Serialize + 'static,
102    {
103        self.ctx.send(self.request_target, self.req, None)
104    }
105
106    /// Schedule the request to the service, without waiting for the response.
107    pub fn send_with_delay(self, duration: Duration)
108    where
109        Req: Serialize + 'static,
110    {
111        self.ctx.send(self.request_target, self.req, Some(duration))
112    }
113}