Rust GraphQL客户端工具graphql_client_cli的使用,支持高效查询与代码自动生成
Rust GraphQL客户端工具graphql_client_cli的使用,支持高效查询与代码自动生成
安装
cargo install graphql_client_cli --force
获取Schema
从运行的GraphQL API获取schema,schema会输出到stdout。
graphql-client introspect-schema [FLAGS] [OPTIONS] <schema_location>
参数说明:
FLAGS:
-h, --help 显示帮助信息
-V, --version 显示版本信息
--no-ssl 禁用SSL证书验证(默认false)
OPTIONS:
--authorization <authorization> 设置Authorization头内容
--header <headers>... 指定自定义头(格式: 'X-Name: Value')
--output <output> 指定输出JSON schema的路径
ARGS:
<schema_location> GraphQL端点URL
生成客户端代码
graphql-client generate [FLAGS] [OPTIONS] <query_path> --schema-path <schema_path>
参数说明:
FLAGS:
-h, --help 显示帮助信息
--no-formatting 不执行rustfmt格式化生成的代码(默认false)
-V, --version 显示版本信息
OPTIONS:
-I, --variables-derives <variables_derives>
为变量生成的struct和enum添加额外的derive(例: --variables-derives='Serialize,PartialEq')
-O, --response-derives <response_derives>
为响应生成的struct和enum添加额外的derive(例: --response-derives='Serialize,PartialEq')
-d, --deprecation-strategy <deprecation_strategy>
选择弃用策略: allow, deny或warn(默认warn)
-m, --module-visibility <module_visibility>
选择模块和结构体可见性: pub或private(默认pub)
-o, --output-directory <output_directory>
代码生成的目标目录
-s, --schema-path <schema_path>
GraphQL schema文件路径(.json或.graphql)
-o, --selected-operation <selected_operation>
目标查询名称。如果不设置此参数,则生成query文件中的所有查询
--fragments-other-variant
为fragment生成的enum添加Unknown变体
ARGS:
<query_path> GraphQL查询文件路径
如果要使用格式化功能,需要这样安装:
cargo install graphql_client_cli
完整示例
示例1:获取GraphQL Schema
# 从GitHub API获取schema并保存到schema.json
graphql-client introspect-schema https://api.github.com/graphql \
--output schema.json \
--header "Authorization: bearer YOUR_GITHUB_TOKEN"
示例2:生成客户端代码
首先创建一个查询文件 query.graphql
:
query GetUser($login: String!) {
user(login: $login) {
login
name
bio
location
websiteUrl
}
}
然后运行生成命令:
graphql-client generate query.graphql \
--schema-path schema.json \
--output-directory src/graphql \
--variables-derives "Serialize,Deserialize" \
--response-derives "Serialize,Deserialize"
这将在 src/graphql
目录生成Rust客户端代码。
示例3:使用生成的客户端代码
use graphql_client::{GraphQLQuery, Response};
use serde_json::json;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json",
query_path = "query.graphql",
response_derives = "Debug,Serialize,Deserialize",
variables_derives = "Debug,Serialize,Deserialize"
)]
pub struct GetUser;
async fn fetch_user(login: String) -> Result<(), reqwest::Error> {
let variables = get_user::Variables { login };
let request_body = GetUser::build_query(variables);
let client = reqwest::Client::new();
let res = client
.post("https://api.github.com/graphql")
.header("Authorization", "bearer YOUR_GITHUB_TOKEN")
.json(&request_body)
.send()
.await?;
let response_body: Response<get_user::ResponseData> = res.json().await?;
println!("{:?}", response_body.data);
Ok(())
}
完整示例demo
以下是基于上述示例的完整demo:
// 主要依赖
use graphql_client::{GraphQLQuery, Response};
use reqwest;
use serde_json;
// 定义查询结构体
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.json", // schema文件路径
query_path = "query.graphql", // 查询文件路径
response_derives = "Debug,Serialize,Deserialize", // 响应结构体derive
variables_derives = "Debug,Serialize,Deserialize" // 变量结构体derive
)]
pub struct GetUser;
// 异步函数获取用户信息
async fn fetch_github_user(login: String) -> Result<(), reqwest::Error> {
// 构造查询变量
let variables = get_user::Variables { login };
// 构建查询请求体
let request_body = GetUser::build_query(variables);
// 创建HTTP客户端
let client = reqwest::Client::new();
// 发送请求并获取响应
let res = client
.post("https://api.github.com/graphql")
.header("Authorization", "bearer YOUR_GITHUB_TOKEN") // 替换为你的token
.json(&request_body)
.send()
.await?;
// 解析响应数据
let response_body: Response<get_user::ResponseData> = res.json().await?;
// 打印用户数据
if let Some(data) = response_body.data {
println!("用户登录名: {}", data.user.login);
println!("用户名: {}", data.user.name.unwrap_or_default());
println!("用户简介: {}", data.user.bio.unwrap_or_default());
println!("用户位置: {}", data.user.location.unwrap_or_default());
println!("个人网站: {}", data.user.website_url.unwrap_or_default());
}
Ok(())
}
// 主函数
#[tokio::main]
async fn main() {
match fetch_github_user("octocat".to_string()).await { // 查询octocat用户信息
Ok(_) => println!("查询成功!"),
Err(e) => eprintln!("查询失败: {:?}", e),
}
}
这个完整demo展示了如何:
- 使用graphql_client_cli工具生成客户端代码
- 定义GraphQL查询结构体
- 构建查询请求
- 处理响应数据
- 在主函数中调用查询函数
要运行这个demo,你需要:
- 按照前面的步骤获取GitHub API的schema
- 创建query.graphql文件
- 生成客户端代码
- 替换YOUR_GITHUB_TOKEN为有效的GitHub token
1 回复
Rust GraphQL客户端工具graphql_client_cli使用指南
完整示例demo
下面是一个完整的示例,展示如何使用graphql_client_cli从GraphQL API获取用户信息:
- 首先创建一个GraphQL schema文件
schema.graphql
:
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Post {
id: ID!
title: String!
content: String!
publishedAt: DateTime!
}
type Query {
user(id: ID!): User
}
scalar DateTime
- 创建查询文件
queries/get_user.graphql
:
query GetUser($id: ID!) {
user(id: $id) {
id
name
email
posts {
title
publishedAt
}
}
}
- 生成Rust代码:
graphql_client_cli --schema schema.graphql --output src/graphql --query queries/get_user.graphql --module
- 创建
build.rs
文件:
fn main() {
println!("cargo:rerun-if-changed=queries/");
println!("cargo:rerun-if-changed=schema.graphql");
let status = std::process::Command::new("graphql_client_cli")
.args(&["--schema", "schema.graphql", "--output", "src/graphql", "--query", "queries/", "--module"])
.status()
.expect("Failed to run graphql_client_cli");
if !status.success() {
panic!("GraphQL code generation failed");
}
}
- 创建
src/graphql/mod.rs
文件:
pub mod get_user;
- 主程序
src/main.rs
:
use graphql_client::{GraphQLQuery, Response};
use std::error::Error;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "schema.graphql",
query_path = "queries/get_user.graphql",
response_derives = "Debug, Serialize, Deserialize"
)]
pub struct GetUser;
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
// 准备查询变量
let variables = get_user::Variables {
id: "123".to_string(),
};
// 构建查询请求体
let request_body = GetUser::build_query(variables);
// 创建HTTP客户端
let client = reqwest::Client::new();
// 发送请求到GraphQL端点
let res = client.post("http://example.com/graphql")
.json(&request_body)
.send()
.await?;
// 解析响应
let response_body: Response<get_user::ResponseData> = res.json().await?;
// 处理响应数据
if let Some(data) = response_body.data {
println!("User: {:?}", data.user);
}
Ok(())
}
- 添加必要的依赖到
Cargo.toml
:
[dependencies]
graphql_client = "0.11"
reqwest = { version = "0.11", features = ["json"] }
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"] }
- 配置文件
graphql_client.toml
(可选):
[scalars]
DateTime = "chrono::DateTime<chrono::Utc>"
这个完整示例展示了如何:
- 定义GraphQL schema和查询
- 自动生成类型安全的Rust代码
- 集成到Rust项目中
- 发送GraphQL请求并处理响应
- 配置自定义标量类型
你可以根据需要修改查询、schema和请求处理逻辑来适应你的具体项目需求。