使用 Rust 构建 GraphQL API:逐步实践教程

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

引言:为什么 Rust 和 GraphQL 是理想组合

\n

现代 Web 开发需要高性能和强类型。Rust 以其内存安全性和速度著称,成为构建后端的绝佳选择。而 GraphQL 则提供了一种灵活高效的数据处理方式。在本教程中,我们将使用 async-graphql 库和 actix-web 框架,用 Rust 构建一个完整的 GraphQL API。您将学习如何定义模式、编写解析器以及处理请求。

\n

到文章结尾,您将拥有一个可运行的服务端,随时可集成到实际项目中。所有代码示例均经过验证,可直接运行。

\n\n

项目配置与依赖安装

\n

首先,创建一个新的 Rust 项目。请确保您已安装 Rust(建议版本 1.75+)。

\n
cargo new graphql-rust-api\ncd graphql-rust-api
\n

打开 Cargo.toml 并添加以下依赖:

\n
[dependencies]\nactix-web = "4"\nactix-rt = "2"\nasync-graphql = "7"\nasync-graphql-actix-web = "7"\nserde = { version = "1", features = ["derive"] }\ntokio = { version = "1", features = ["macros"] }
\n

运行 cargo build 以下载并编译所有依赖。首次运行可能需要几分钟。

\n\n

项目结构

\n

创建以下文件夹和文件结构:

\n
src/\n├── main.rs\n├── schema.rs\n├── models.rs\n└── resolvers.rs
\n

我们将逐步填充每个文件。

\n\n

定义 GraphQL 模型与模式

\n

首先创建一个简单的数据模型。在 models.rs 中描述 User 结构体:

\n
use serde::{Deserialize, Serialize};\n\n#[derive(Debug, Clone, Serialize, Deserialize)]\npub struct User {\n    pub id: u32,\n    pub name: String,\n    pub email: String,\n}
\n

现在转到 schema.rs。在这里定义 GraphQL 对象和查询:

\n
use async_graphql::{Context, Object, SimpleObject};\nuse crate::models::User;\nuse crate::resolvers::get_all_users;\n\n#[derive(SimpleObject)]\npub struct UserObject {\n    pub id: u32,\n    pub name: String,\n    pub email: String,\n}\n\npub struct QueryRoot;\n\n#[Object]\nimpl QueryRoot {\n    async fn users(&self, ctx: &Context<'_>) -> Vec<UserObject> {\n        let users = get_all_users(ctx).await;\n        users.into_iter().map(|u| UserObject {\n            id: u.id,\n            name: u.name,\n            email: u.email,\n        }).collect()\n    }\n}
\n

注意使用 #[derive(SimpleObject)]——这是 async-graphql 的宏,用于自动生成 GraphQL 类型。

\n\n

解析器:业务逻辑

\n

在 resolvers.rs 文件中实现数据获取函数。为简单起见,我们使用静态列表:

\n
use async_graphql::Context;\nuse crate::models::User;\n\npub async fn get_all_users(_ctx: &Context<'_>) -> Vec<User> {\n    vec![\n        User { id: 1, name: "Alice".into(), email: "alice@example.com".into() },\n        User { id: 2, name: "Bob".into(), email: "bob@example.com".into() },\n        User { id: 3, name: "Charlie".into(), email: "charlie@example.com".into() },\n    ]\n}
\n

在实际项目中,这里可能会涉及数据库或外部 API 的调用。

\n\n

在 Actix-web 上构建服务器

\n

现在最关键的一步——在 main.rs 中将所有内容整合在一起:

\n
use actix_web::{web, App, HttpServer, HttpResponse};\nuse async_graphql::{Schema, EmptyMutation, EmptySubscription};\nuse async_graphql_actix_web::{GraphQLRequest, GraphQLResponse};\nuse crate::schema::QueryRoot;\n\nmod models;\nmod schema;\nmod resolvers;\n\ntype AppSchema = Schema<QueryRoot, EmptyMutation, EmptySubscription>;\n\nasync fn graphql_handler(\n    schema                

博客

书籍推荐