14 个重大版本
0.14.0 | 2024 年 3 月 26 日 |
---|---|
0.13.0 | 2023 年 5 月 30 日 |
0.12.0 | 2023 年 1 月 12 日 |
0.11.0 | 2022 年 6 月 21 日 |
0.3.0 | 2018 年 7 月 24 日 |
#6 in HTTP 客户端
469,371 个月下载量
用于 111 个 Crates(90 个直接使用)
35KB
235 行
graphql_client
Rust 的类型化 GraphQL 客户端库。
特性
- 查询变量和响应的精确类型。
- 支持 GraphQL 片段、对象、联合、输入、枚举、自定义标量和输入对象。
- 在浏览器(WebAssembly)中运行。
- 订阅支持(目前仅支持序列化和反序列化)。
- 从 GraphQL 模式复制文档到生成的 Rust 代码。
- 对生成的响应支持任意 derive。
- 支持任意自定义标量。
- 支持查询文档中每个查询多个操作。
- 支持将 GraphQL 字段设置为已弃用,并由 Rust 编译器检查其使用。
- 可选的基于 reqwest 的客户端,用于从浏览器进行无样板 API 调用。
- 显式和隐式空支持。
入门指南
-
如果您不熟悉 GraphQL,官方网站 https://graphql.net.cn/ 提供了非常好的全面介绍。
-
一旦您编写了查询(很可能是使用 graphiql 等),将其保存到项目中的
.graphql
文件中。 -
为了为响应提供精确的类型,graphql_client 需要在编译时读取查询和模式。
下载模式有多种选择。该项目提供了一个 CLI,但使用什么工具无关紧要,生成的
schema.json
是相同的。 -
我们现在拥有了为我们的查询推导 Rust 类型的所有必要信息。这通过一个过程宏实现,如下面的代码片段所示
use graphql_client::GraphQLQuery; // The paths are relative to the directory where your `Cargo.toml` is located. // Both json and the GraphQL schema language are supported as sources for the schema #[derive(GraphQLQuery)] #[graphql( schema_path = "tests/unions/union_schema.graphql", query_path = "tests/unions/union_query.graphql", )] pub struct UnionQuery;
例如,
derive
将生成一个名为union_query
的模块 - 名称是结构体的名称,但以蛇形命名。该模块包含所有必要的结构和枚举定义,以反序列化该查询的响应。
响应的根类型被命名为
ResponseData
。GraphQL 响应将采用以下形式Response<ResponseData>
(Response 类型始终相同)。该模块还包含一个名为
Variables
的结构体,表示查询所需的变量。
-
我们现在需要创建要发送到服务器的完整负载。为了方便,GraphQLQuery trait 已在 derive 结构体中实现,因此可以通过这种方式创建完整的查询体
use graphql_client::{GraphQLQuery, Response}; use std::error::Error; use reqwest; #[derive(GraphQLQuery)] #[graphql( schema_path = "tests/unions/union_schema.graphql", query_path = "tests/unions/union_query.graphql", response_derives = "Debug", )] pub struct UnionQuery; async fn perform_my_query(variables: union_query::Variables) -> Result<(), Box<dyn Error>> { // this is the important line let request_body = UnionQuery::build_query(variables); let client = reqwest::Client::new(); let mut res = client.post("/graphql").json(&request_body).send().await?; let response_body: Response<union_query::ResponseData> = res.json().await?; println!("{:#?}", response_body); Ok(()) }
使用 CLI 的替代工作流程
您可以使用命令行界面到库的库来内省 GraphQL API 并生成模块
$ cargo install graphql_client_cli
$ graphql-client --help
在响应上派生特定特性
生成的响应类型始终派生自 serde::Deserialize
,但您可能想要打印它们(Debug
),比较它们(PartialEq
)或派生其上的任何其他特性。您可以通过 response_derives
选项实现此功能 graphql
特性。例如
use graphql_client::GraphQLQuery;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "tests/unions/union_schema.graphql",
query_path = "tests/unions/union_query.graphql",
response_derives = "Serialize,PartialEq",
)]
struct UnionQuery;
隐式空值
生成的代码将跳过 None
值的序列化。
use graphql_client::GraphQLQuery;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "tests/unions/union_schema.graphql",
query_path = "tests/unions/union_query.graphql",
skip_serializing_none
)]
struct UnionQuery;
自定义标量
在 GraphQL 中,有五种标量类型 Int
、Float
、String
、Boolean
和 ID
可用,并且自动映射到 Rust 中的等效类型。但是,服务提供商还可以通过将声明如 scalar URI
添加到服务器模式来定义自定义标量类型。
如果在该模式中定义了此类自定义标量类型,则生成的代码将根据查询的内容引用这些标量类型。这意味着您必须在 derive 结构体的作用域内提供匹配的 Rust 类型。它可以像声明 type URI = String;
一样简单。这使您能够完全自由地处理自定义标量,只要它们可以被反序列化。如果没有提供此类声明,您将得到类似这样的构建错误
error[E0412]: cannot find type `URI` in module `super`
|
| #[derive(GraphQLQuery)]
| ^^^^^^^^^^^^ not found in `super`
|
= note: possible candidate is found in another module, you can import it into scope:
crate::repo_view::URI
弃用
生成的代码支持 @deprecated
字段注解。您可以通过 GraphQLQuery
derive 中的 deprecated
参数配置如何处理弃用
use graphql_client::GraphQLQuery;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "tests/unions/union_schema.graphql",
query_path = "tests/unions/union_query.graphql",
deprecated = "warn"
)]
pub struct UnionQuery;
有效的值是
allow
:响应结构体字段不被标记为弃用。warn
:响应结构体字段被标记为#[deprecated]
。deny
:结构体字段不包括在响应结构体中,使用它们会导致编译错误。
默认值为 warn
。
具有多个操作的查询文档
您可以在一个查询文档(一个 .graphql
文件)中编写多个操作。然后,您可以通过将具有与操作之一相同名称的结构体命名为 #[derive(GraphQLQuery)]
来选择其中一个。这样很方便,因为它允许操作之间共享片段。
请注意,GraphQL文件中的结构和操作 必须 有相同的名称。我们强制执行此要求以使生成的代码更可预测。
use graphql_client::GraphQLQuery;
#[derive(GraphQLQuery)]
#[graphql(
schema_path = "tests/unions/union_schema.graphql",
query_path = "tests/unions/union_query.graphql",
)]
pub struct UnionQuery;
有关示例,请参阅 测试中的示例。
生成模块的文档
您可以使用 cargo doc --document-private-items
在生成的代码上生成rustdoc文档。
当 .graphql 文件更改时使 cargo 重新编译
您可以在您的 Cargo.toml
中添加一个 include
选项。然而,目前它存在一些问题(见 此问题)。
示例
请参阅此存储库中的 示例目录。
贡献者
对所有以任何方式(不仅仅是代码)为此项目做出贡献的人表示衷心的感谢
- Alex Vlasov (@indifferentalex)
- Ben Boeckel (@mathstuf)
- Chris Fung (@aergonaut)
- Christian Legnitto (@LegNeato)
- David Gräff (@davidgraeff)
- Dirkjan Ochtman (@djc)
- Fausto Nunez Alberro (@brainlessdeveloper)
- Hirokazu Hata (@h-michael)
- Peter Gundel (@peterfication)
- Sonny Scroggin (@scrogson)
- Sooraj Chandran (@SoorajChandran)
- Tom Houlé (@tomhoule)
行为准则
任何与本项目互动的人,包括但不限于此GitHub仓库,都必须遵守我们的 行为准则。
许可证
许可方式如下
- Apache License, Version 2.0, (LICENSE-APACHE 或 https://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 https://opensource.org/licenses/MIT)
贡献
除非您明确表示,否则您有意提交以包含在本作品中(根据Apache-2.0许可证定义),则应按上述方式双许可,而无需任何额外条款或条件。
依赖项
~2–15MB
~226K SLoC