Rust 中的 HTTP 客户端:正确发起请求
Rust 是一种现代系统编程语言,因其高性能和内存安全性而广受欢迎。然而,许多习惯使用 Python 或 JavaScript 的开发者会问:如何在 Rust 中发起 HTTP 请求?本文将指导你使用流行的 reqwest 库在 Rust 中创建 HTTP 客户端。你将学习如何发送 GET 和 POST 请求、处理 JSON、管理请求头以及处理异步操作。阅读后,你将能够自信地将 HTTP 客户端集成到你的 Rust 项目中。
1. 安装与环境配置
首先,创建一个新的 Rust 项目并添加必要的依赖。打开终端并运行:
cargo new http_client_rustcd http_client_rust现在编辑 Cargo.toml 文件,添加以下依赖:
[dependencies]reqwest = { version = "0.11", features = ["json"] }tokio = { version = "1", features = ["full"] }serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"我们来逐一解释每个库的作用:
- reqwest — 主要 HTTP 客户端。
json标志添加了对 JSON 序列化/反序列化的支持。 - tokio — 异步运行时,是 reqwest 在异步模式下工作的必要条件。
- serde 和 serde_json — 用于处理 JSON 数据结构。
添加完依赖后,运行 cargo build 以下载并编译所有库。
2. 基础 GET 请求
让我们从一个简单的 GET 请求开始,调用一个公共 API。我们将创建一个用于接收响应的数据结构,并向 JSONPlaceholder 服务发起请求:
use reqwest;use serde::Deserialize;
#[derive(Debug, Deserialize)]struct Post { userId: u32, id: u32, title: String, body: String,}
#[tokio::main]async fn main() -> Result<(), reqwest::Error> { let url = "https://jsonplaceholder.typicode.com/posts/1"; let response = reqwest::get(url).await?; let post: Post = response.json().await?; println!("{:#?}", post); Ok(())}代码解析:
#[derive(Debug, Deserialize)]属性自动生成用于打印和反序列化的 trait。#[tokio::main]将函数转变为异步入口点。reqwest::get()执行 GET 请求,.await等待其完成。response.json()将 JSON 响应转换为我们的数据结构。
使用 cargo run 命令运行代码。你将在控制台中看到帖子的数据。
3. 带数据发送的 POST 请求
现在来看看如何向服务器发送数据。对于 POST 请求,我们需要创建一个用于发送数据的数据结构,并使用 post() 方法:
use reqwest::Client;use serde::{Deserialize, Serialize};
#[derive(Debug, Serialize)]struct NewPost { title: String, body: String, userId: u32,}
#[derive(Debug, Deserialize)]struct CreatedPost { id: u32, title: String, body: String, userId: u32,}
#[tokio::main]async fn main() -> Result<(), reqwest::Error> { let client = Client::new(); let new_post = NewPost { title: "我的第一个 Rust 帖子".to_string(), body: "这是使用 reqwest 发送的帖子内容".to_string(), userId: 1, }; let response = client .post("https://jsonplaceholder.typicode.com/posts") .json(&new_post) .send() .await?; let created_post: CreatedPost = response.json().await?; println!("创建的帖子 ID: {}", created_post.id); println