Skip to main content

sz_orm_graphql/
resolver.rs

1//! DB Resolver trait — P2-1 修复 C-3:真实 DB resolver 集成
2//!
3//! 定义 GraphQL root field 与真实数据源(数据库/ORM)之间的桥接接口。
4//!
5//! # 设计
6//!
7//! - 使用 boxed future 手动实现 async trait,避免引入 async-trait 依赖
8//! - 调用方实现此 trait 后,通过 `GraphQLServer::with_db_resolver` 注入
9//! - 未注入 resolver 时,schema 回退到 mock 数据(向后兼容)
10//!
11//! # 使用示例
12//!
13//! ```ignore
14//! use sz_orm_graphql::resolver::{DbResolver, ResolverContext};
15//! use std::sync::Arc;
16//!
17//! struct MyDbResolver;
18//!
19//! impl DbResolver for MyDbResolver {
20//!     fn resolve_query(
21//!         &self,
22//!         ctx: &ResolverContext,
23//!     ) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<serde_json::Value, String>> + Send>> {
24//!         let field_name = ctx.field_name.clone();
25//!         let args = ctx.args.clone();
26//!         Box::pin(async move {
27//!             // 在此处执行真实数据库查询
28//!             Ok(serde_json::json!({"id": "1", "name": format!("{}_real", field_name)}))
29//!         })
30//!     }
31//! }
32//!
33//! let resolver = Arc::new(MyDbResolver);
34//! let server = sz_orm_graphql::GraphQLServer::new(4000)
35//!     .with_schema(schema)
36//!     .with_db_resolver(resolver);
37//! ```
38
39use serde_json::Value;
40use std::future::Future;
41use std::pin::Pin;
42use std::sync::Arc;
43
44/// Resolver 调用上下文 — 传递字段名、参数等信息给 resolver
45#[derive(Debug, Clone)]
46pub struct ResolverContext {
47    /// Root field 名称(如 "getUser"、"listUsers")
48    pub field_name: String,
49    /// 字段类型名(如 "User"、"[User!]!")
50    pub type_name: String,
51    /// 是否为列表查询
52    pub is_list: bool,
53    /// GraphQL 参数(从查询中提取,如 {"id": "1"})
54    pub args: Value,
55}
56
57/// DB Resolver trait — P2-1 修复 C-3
58///
59/// 调用方实现此 trait,为 GraphQL root field 提供真实数据。
60///
61/// # 方法
62///
63/// - `resolve_query`:解析 Query 字段,返回单个对象或数组
64/// - `resolve_mutation`:解析 Mutation 字段,返回操作结果
65///
66/// # async 实现
67///
68/// 使用 `Pin<Box<dyn Future>>` 返回异步结果,无需 async-trait 依赖。
69pub trait DbResolver: Send + Sync {
70    /// 解析 Query root field
71    ///
72    /// # 参数
73    ///
74    /// - `ctx`:resolver 上下文(字段名、参数等)
75    ///
76    /// # 返回
77    ///
78    /// - `Ok(Value)`:解析结果(单个对象为 `Value::Object`,列表为 `Value::Array`)
79    /// - `Err(String)`:解析错误
80    fn resolve_query(
81        &self,
82        ctx: &ResolverContext,
83    ) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>>;
84
85    /// 解析 Mutation root field
86    ///
87    /// 默认实现返回错误,调用方按需覆盖。
88    fn resolve_mutation(
89        &self,
90        ctx: &ResolverContext,
91    ) -> Pin<Box<dyn Future<Output = Result<Value, String>> + Send>> {
92        let _ = ctx;
93        Box::pin(async { Err("Mutation resolver not implemented".to_string()) })
94    }
95}
96
97/// 类型别名:Arc 包装的 DbResolver
98pub type SharedDbResolver = Arc<dyn DbResolver>;