Rust HTTP客户端:从A到Z正确发起请求

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

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

开始课程

引言:为什么要在Rust中编写HTTP客户端?

现代开发很少能不依赖与外部服务的交互。无论是天气REST API、数据库还是微服务架构——发送HTTP请求的能力都是一项基本技能。Rust以其对性能和安全的重视,提供了几种优雅的HTTP处理方案。在本文中,我们将探讨如何在Rust中正确创建HTTP客户端:从库的选择到复杂场景的处理。



我们将介绍两个最流行的库:reqwest(异步标准)和ureq(简单的同步方法)。您将学习如何发送GET和POST请求、处理JSON、管理标头以及避免常见错误。



1. 库的选择:reqwest vs ureq



在编写代码之前,需要确定使用哪个工具。Rust生态系统中有两个主要候选。



1.1. Reqwest——强大且异步

reqwest是Rust中HTTP请求的事实标准。它基于hyper和tokio构建,支持异步、自动JSON序列化/反序列化以及cookie处理。非常适合高负载应用和Web服务器。



首先,在Cargo.toml中添加:

[dependencies]reqwest = { version = "0.12", features = ["json"] }tokio = { version = "1", features = ["full"] }serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"


1.2. Ureq——无需异步的简洁性

如果您不需要异步调用,并且正在编写简单的脚本或CLI工具,ureq将是一个很好的选择。它是同步的、极简的,并且不需要复杂的运行时配置。



[dependencies]ureq = "2.9"serde = { version = "1.0", features = ["derive"] }serde_json = "1.0"


何时选择哪个? 对于Web服务器和复杂应用——选择reqwest。对于简单任务、测试和脚本——选择ureq。



2. 基本请求:GET和POST



让我们看看两个库的实际示例。



2.1. 使用reqwest的GET请求

最简单的示例——从公共API获取数据。我们使用带有#[tokio::main]宏的异步main函数。



use reqwest;use std::error::Error;

#[tokio::main]async fn main() -> Result<(), Box<dyn Error>> { let url = "https://jsonplaceholder.typicode.com/posts/1"; let response = reqwest::get(url).await?;

// 检查响应状态 if response.status().is_success() { let body = response.text().await?; println!("响应: {}", body); } else { eprintln!("HTTP错误: {}", response.status()); }

Ok(())}


2.2. 使用JSON体的POST请求(reqwest)

发送数据通常需要序列化结构体。为此,我们使用serde crate。



use reqwest;use serde::{Deserialize, Serialize};use std::error::Error;

#[derive(Serialize, Deserialize, Debug)]struct Post { title: String, body: String, user_id: i32,}

#[tokio::main]async fn main() -> Result<(), Box<dyn Error>> { let client = reqwest::Client::new(); let new_post = Post { title: "Hello Rust".to_string(), body: "这是请求体".to_string(), user_id: 1, };

let response = client .post("https://jsonplaceholder.typicode.com/posts") .json(&new_post) .send() .await?;

let created_post: Post = response.json().await?; println!("创建的帖子: {:?}", created_post);

Ok(())}


2.3. 使用ureq的简单GET请求

使用ureq,代码变得更短,因为它不需要异步:



use ureq;use std::error::Error;

fn

博客

书籍推荐