Rust 与 API:从 REST 到 gRPC——快速且安全地编写

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

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

开始课程

为什么 Rust 是使用 API 的理想选择?

\n\n

如果你还以为 Rust 只适用于系统编程和替代 C++,那你就严重落后于现实了。Rust 已经自信地闯入了 Web 开发和后端服务领域。而且不仅仅是闯入,它还在那些重视速度、可靠性和内存安全的细分市场中占据了一席之地。

\n\n

但老实说:在 Rust 中使用 API 不仅仅是“拿一个现成的库就用”。它是在语言强大功能与开发便利性之间寻求平衡的艺术。在本文中,我们将分析三种主要方法:REST、GraphQL 和 gRPC。每种方法各有千秋,选择取决于你的具体任务。我们开始吧!

\n\n

Rust 中的 REST:行之有效的经典方案

\n\n

REST 仍然是最流行的 API 风格。它简单、直观,并且几乎受到所有平台的支持。Rust 有几个优秀的框架,但其中的王者是 actix-web。它快速、异步,并且拥有出色的生态系统。

\n\n

使用 actix-web 编写一个简单的 REST 服务

\n\n

让我们创建一个用于管理任务列表 (todo) 的微型服务。我们需要 actix-web、用于序列化的 serde 以及作为异步运行时的 tokio。

\n\n
// Cargo.toml\n// [dependencies]\n// actix-web = "4"\n// serde = { version = "1", features = ["derive"] }\n// serde_json = "1"\n// tokio = { version = "1", features = ["full"] }\n\nuse actix_web::{get, post, web, App, HttpResponse, HttpServer, Responder};\nuse serde::{Deserialize, Serialize};\nuse std::sync::Mutex;\n\n#[derive(Serialize, Deserialize, Clone)]\nstruct Task {\n    id: u32,\n    title: String,\n    completed: bool,\n}\n\nstruct AppState {\n    tasks: Mutex<Vec<Task>>,\n}\n\n#[get("/tasks")]\nasync fn get_tasks(data: web::Data<AppState>) -> impl Responder {\n    let tasks = data.tasks.lock().unwrap();\n    HttpResponse::Ok().json(tasks.clone())\n}\n\n#[post("/tasks")]\nasync fn create_task(data: web::Data<AppState>, body: web::Json<Task>) -> impl Responder {\n    let mut tasks = data.tasks.lock().unwrap();\n    let new_id = tasks.len() as u32 + 1;\n    let task = Task {\n        id: new_id,\n        title: body.title.clone(),\n        completed: false,\n    };\n    tasks.push(task.clone());\n    HttpResponse::Created().json(task)\n}\n\n#[actix_web::main]\nasync fn main() -> std::io::Result<()> {\n    let state = web::Data::new(AppState {\n        tasks: Mutex::new(vec![]),\n    });\n\n    HttpServer::new(move || {\n        App::new()\n            .app_data(state.clone())\n            .service(get_tasks)\n            .service(create_task)\n    })\n    .bind("127.0.0.1:8080")?\n    .run()\n    .await\n}\n
\n\n

这段代码的美妙之处在于它是内存安全的,并且不需要垃圾回收器。actix-web 利用 Rust 的异步机制,可以在单个线程上每秒处理数千个请求。尝试运行一下——你会惊讶于即使在性能较弱的硬件上它也能如此快速。

\n\n

什么时候 REST 不是最佳选择?

\n\n

REST 非常适合 CRUD 操作,但如果需要灵活地查询数据(例如,嵌套资源),REST 就会开始需要大量的端点。这时,GraphQL 就登场了。

\n\n

Rust 中的 GraphQL:灵活无痛

\n\n

GraphQL 允许客户端精确地请求所需的数据。对于 Rust 来说,最佳选择是 async-graphql。它与 actix-web 紧密集成,并提供了强大的 DSL 来描述模式。

\n\n

示例:图书管理 API

\n\n

假设我们想让客户端能够查询书籍和作者。使用 GraphQL,只需一个模式即可完成。

\n\n
// Cargo.toml\n// [dependencies]\n// async-graphql = "7"\n// async-graphql-actix-web = "7"\n// actix-web = "4"\n// serde = { version = "1", features = ["derive"] }\n\nuse async_graphql::{Context, EmptyMutatio                

博客

书籍推荐