Appearance
GraphQL字段类型与约束定义
本文档引用的文件
目录
引言
本文档深入探讨了在Rust后端系统中GraphQL字段的定义方式,重点分析了usr_graphql.rs
文件中用户模块的字段声明。文档详细说明了如何通过类型系统设置字段描述、默认值和可空性,并阐述了验证器在字段约束中的集成方式,展示了业务规则如何通过类型系统强制执行。
GraphQL字段类型系统
GraphQL字段类型系统在本项目中通过async-graphql
库实现,提供了完整的类型安全和验证机制。系统支持标量类型(如String、Int、Boolean)和自定义复合类型,通过Rust的宏系统和类型注解实现。
图表来源
本节来源
标量类型与自定义类型
标量类型使用
在GraphQL字段定义中,系统广泛使用了Rust内置的标量类型:
- String: 用于文本字段如用户名、名称、备注等
- Int: 使用
u32
表示排序字段,u8
表示布尔标志 - Boolean: 通过
u8
值(0或1)表示启用/锁定状态 - ID: 通过
UsrId
类型表示用户ID
自定义类型定义
系统定义了多种自定义类型来满足业务需求:
图表来源
本节来源
字段属性配置
字段描述设置
通过Rust文档注释和GraphQL属性宏设置字段描述:
rust
/// 用户名
#[graphql(name = "username")]
pub username: String,
默认值配置
系统通过Default
trait和#[default]
属性设置默认值:
rust
#[derive(SimpleObject, Default, Serialize, Deserialize, Clone, Debug)]
#[graphql(rename_fields = "snake_case", name = "UsrModel")]
pub struct UsrModel {
/// 类型
#[graphql(name = "type")]
pub r#type: UsrType, // 默认为Login
}
可空性管理
通过Option<T>
类型精确控制字段的可空性:
图表来源
本节来源
验证器集成机制
验证器架构
系统采用模块化验证器设计,将验证逻辑与业务逻辑分离:
图表来源
字符串长度验证
chars_max_length.rs
验证器实现字符串长度约束:
rust
pub fn chars_max_length(
value: Option<String>,
len: usize,
label: &str,
) -> Result<()> {
if value.is_none() {
return Ok(());
}
let value = value.unwrap();
let value_len = value.chars().count();
if value_len <= len {
return Ok(());
}
let err_msg = format!("The {label} length cannot greater than {len}");
Err(eyre!(err_msg))
}
邮件格式验证
email.rs
验证器实现邮件格式验证:
rust
pub async fn email(
value: Option<String>,
label: &str,
) -> Result<()> {
if value.is_none() {
return Ok(());
}
let value = value.unwrap();
if is_valid_email(&value) {
return Ok(());
}
let msg = ns("邮件格式不正确".to_owned(), None).await?;
let mut err_msg = String::new();
err_msg.push_str(label);
err_msg.push(' ');
err_msg.push_str(&msg);
Err(eyre!(err_msg))
}
本节来源
业务规则强制执行
类型安全执行
通过Rust的类型系统确保业务规则:
图表来源
锁定状态验证
系统通过验证器强制执行锁定状态规则:
rust
pub async fn update_by_id_usr(
usr_id: UsrId,
mut usr_input: UsrInput,
options: Option<Options>,
) -> Result<UsrId> {
let is_locked = usr_dao::get_is_locked_by_id_usr(
usr_id,
None,
).await?;
if is_locked {
let err_msg = "不能修改已经锁定的 用户";
return Err(eyre!(err_msg));
}
// 继续处理...
}
本节来源
带验证逻辑的字段定义示例
用户名字段验证
结合长度和格式验证的用户名字段:
图表来源
本节来源
结论
本系统通过GraphQL与Rust类型系统的深度集成,实现了强大的字段定义和验证机制。标量类型和自定义类型的灵活使用,结合验证器模块的集成,确保了业务规则在类型层面得到强制执行。这种设计不仅提高了代码的类型安全性,还增强了系统的可维护性和可扩展性。