API Responses
Build consistent API responses with rok-utils.
Basic Response
#![allow(unused)]
fn main() {
use serde::Serialize;
#[derive(Debug, Serialize)]
struct ApiResponse<T> {
success: bool,
data: Option<T>,
error: Option<String>,
}
impl<T> ApiResponse<T> {
fn ok(data: T) -> Self {
Self {
success: true,
data: Some(data),
error: None,
}
}
fn err(message: &str) -> Self {
Self {
success: false,
data: None,
error: Some(message.to_string()),
}
}
}
}
JSON API Response
#![allow(unused)]
fn main() {
use serde::{Deserialize, Serialize};
use serde_json::json;
use rok_utils::str::Str;
#[derive(Debug, Serialize)]
struct ApiResponse {
success: bool,
message: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
data: Option<serde_json::Value>,
}
impl ApiResponse {
fn success(message: &str) -> Self {
Self {
success: true,
message: Some(message.to_string()),
data: None,
}
}
fn success_with_data(data: serde_json::Value) -> Self {
Self {
success: true,
message: None,
data: Some(data),
}
}
fn error(message: &str) -> Self {
Self {
success: false,
message: Some(message.to_string()),
data: None,
}
}
}
}
Using with RokError
#![allow(unused)]
fn main() {
use serde::Serialize;
use rok_utils::{RokError, RokResultExt, Str};
#[derive(Debug, Serialize)]
struct ApiResponse<T> {
success: bool,
data: Option<T>,
error: Option<ErrorDetail>,
}
#[derive(Debug, Serialize)]
struct ErrorDetail {
code: String,
message: String,
#[serde(skip_serializing_if = "Option::is_none")]
field: Option<String>,
}
impl ApiResponse<String> {
fn from_result<T: Serialize>(result: Result<T, RokError>) -> Self {
match result {
Ok(data) => Self {
success: true,
data: Some(serde_json::to_value(data).unwrap()),
error: None,
},
Err(err) => Self {
success: false,
data: None,
error: Some(ErrorDetail {
code: err.code().to_string(),
message: err.to_string(),
field: None,
}),
},
}
}
}
}
Example Usage
use serde_json::json;
fn main() {
// Success response
let users = json!([{"id": 1, "name": "Alice"}, {"id": 2, "name": "Bob"}]);
let response = ApiResponse::success_with_data(users);
println!("{}", serde_json::to_string_pretty(&response).unwrap());
// Error response
let err = RokError::ValidationFailure {
field: "email".to_string(),
reason: "Invalid format".to_string(),
};
let response = ApiResponse::<serde_json::Value>::from_result(Err(err));
println!("{}", serde_json::to_string_pretty(&response).unwrap());
}