openlark_platform/app_engine/apaas/v1/application/flow/
execute.rs1use openlark_core::{
7 SDKResult,
8 api::{ApiRequest, ApiResponseTrait, ResponseFormat},
9 config::Config,
10 http::Transport,
11 req_option::RequestOption,
12};
13use serde::{Deserialize, Serialize};
14
15#[derive(Debug, Clone)]
17pub struct FlowExecuteRequestBuilder {
18 config: Config,
19 namespace: String,
21 flow_id: String,
23 params: serde_json::Value,
25}
26
27impl FlowExecuteRequestBuilder {
28 pub fn new(config: Config, namespace: impl Into<String>, flow_id: impl Into<String>) -> Self {
30 Self {
31 config,
32 namespace: namespace.into(),
33 flow_id: flow_id.into(),
34 params: serde_json::json!({}),
35 }
36 }
37
38 pub fn params(mut self, params: impl Into<serde_json::Value>) -> Self {
40 self.params = params.into();
41 self
42 }
43
44 pub async fn execute(self) -> SDKResult<FlowExecuteResponse> {
46 self.execute_with_options(RequestOption::default()).await
47 }
48
49 pub async fn execute_with_options(
51 self,
52 option: RequestOption,
53 ) -> SDKResult<FlowExecuteResponse> {
54 let url = format!(
55 "/open-apis/apaas/v1/applications/{}/flows/{}/execute",
56 self.namespace, self.flow_id
57 );
58
59 let request = FlowExecuteRequest {
60 params: self.params,
61 };
62
63 let req: ApiRequest<FlowExecuteResponse> =
64 ApiRequest::post(&url).body(serde_json::to_value(&request)?);
65 Transport::request_typed(req, &self.config, Some(option), "Operation").await
66 }
67}
68
69#[derive(Debug, Clone, Deserialize, Serialize)]
71struct FlowExecuteRequest {
72 #[serde(rename = "params")]
74 params: serde_json::Value,
75}
76
77#[derive(Debug, Clone, Deserialize, Serialize)]
79pub struct FlowExecuteResponse {
80 #[serde(rename = "instance_id")]
82 pub instance_id: String,
83 #[serde(rename = "status")]
85 pub status: String,
86 #[serde(rename = "message")]
88 pub message: String,
89}
90
91impl ApiResponseTrait for FlowExecuteResponse {
92 fn data_format() -> ResponseFormat {
93 ResponseFormat::Data
94 }
95}
96
97#[deprecated(note = "renamed to FlowExecuteRequestBuilder, will be removed in v1.0 (#271)")]
99pub type FlowExecuteBuilder = FlowExecuteRequestBuilder;
100
101#[cfg(test)]
102mod tests {
103 use super::*;
104
105 #[tokio::test]
107 async fn test_execute_flow_returns_data_on_success() {
108 use serde_json::json;
109 use wiremock::MockServer;
110 use wiremock::matchers::{method, path};
111 use wiremock::{Mock, ResponseTemplate};
112
113 let server = MockServer::start().await;
114 Mock::given(method("POST"))
115 .and(path(
116 "/open-apis/apaas/v1/applications/ns_test/flows/flow_001/execute",
117 ))
118 .respond_with(ResponseTemplate::new(200).set_body_json(json!({
119 "code": 0,
120 "msg": "success",
121 "data": {
122 "instance_id": "inst_001",
123 "status": "RUNNING",
124 "message": "流程已发起"
125 }
126 })))
127 .mount(&server)
128 .await;
129
130 let config = Config::builder()
131 .app_id("ci_app_id")
132 .app_secret("ci_app_secret")
133 .base_url(server.uri())
134 .enable_token_cache(false)
135 .build();
136
137 let resp = FlowExecuteRequestBuilder::new(config, "ns_test", "flow_001")
138 .params(json!({"input": "value"}))
139 .execute()
140 .await
141 .expect("发起流程应成功");
142 assert_eq!(resp.instance_id, "inst_001");
143 assert_eq!(resp.status, "RUNNING");
144 assert_eq!(resp.message, "流程已发起");
145
146 let received = server.received_requests().await.unwrap_or_default();
147 assert_eq!(received.len(), 1);
148 assert_eq!(
149 received[0].url.path(),
150 "/open-apis/apaas/v1/applications/ns_test/flows/flow_001/execute"
151 );
152 }
153}