Skip to main content

feagi_api/common/
request.rs

1// Copyright 2025 Neuraville Inc.
2// SPDX-License-Identifier: Apache-2.0
3
4use serde::{Deserialize, Serialize};
5use std::collections::HashMap;
6
7/// Transport-agnostic API request
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct ApiRequest {
10    /// HTTP method (GET, POST, PUT, DELETE, etc.)
11    pub method: String,
12
13    /// Request path (e.g., "/v1/cortical_area/ipu")
14    pub path: String,
15
16    /// Query parameters
17    #[serde(default)]
18    pub query: HashMap<String, String>,
19
20    /// Request headers (optional)
21    #[serde(default)]
22    pub headers: HashMap<String, String>,
23
24    /// Request body as JSON string (optional)
25    pub body: Option<String>,
26}
27
28impl ApiRequest {
29    pub fn new(method: impl Into<String>, path: impl Into<String>) -> Self {
30        Self {
31            method: method.into(),
32            path: path.into(),
33            query: HashMap::new(),
34            headers: HashMap::new(),
35            body: None,
36        }
37    }
38
39    pub fn with_query(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
40        self.query.insert(key.into(), value.into());
41        self
42    }
43
44    pub fn with_header(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
45        self.headers.insert(key.into(), value.into());
46        self
47    }
48
49    pub fn with_body(mut self, body: impl Into<String>) -> Self {
50        self.body = Some(body.into());
51        self
52    }
53
54    /// Parse body as JSON
55    pub fn parse_body<T: serde::de::DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
56        match &self.body {
57            Some(body) => serde_json::from_str(body),
58            None => serde_json::from_str("{}"), // Return empty object if no body
59        }
60    }
61
62    /// Get query parameter
63    pub fn get_query(&self, key: &str) -> Option<&String> {
64        self.query.get(key)
65    }
66
67    /// Get header value
68    pub fn get_header(&self, key: &str) -> Option<&String> {
69        self.headers.get(key)
70    }
71}