Rust使用 reqwest 发起 GET/POST 异步请求

1、准备工作,在 Cargo.toml 中加入 reqwest 依赖。reqwest 的 async 使用的是 Tokio 的,所以要同时加入 Tokio 的依赖。

[dependencies]
reqwest = { version = "0.10", features = ["json"] }
tokio = { version = "0.2", features = ["full"] }

2、编写GET代码

use std::collections::HashMap;


async fn get() -> Result<HashMap<String, String>, reqwest::Error>{
    Ok(reqwest::get("https://httpbin.org/ip").await?.json::<HashMap<String, String>>().await?)
}

#[tokio::main]
async fn main() {
    if let Ok(resp) = get().await {
        println!("{:#?}", resp);
    }
}

GET 请求代码还是比较简单的,这里不详细解释了。下面看一段 POST 代码,其中包含 Headers 设置和提交 JSON 数据。

3、编写POST代码

use std::collections::HashMap;
use reqwest::header::HeaderMap;
use serde_json::value::Value;

async fn post() -> Result<HashMap<String, Value>, reqwest::Error>{
    // post 请求要创建client
    let client = reqwest::Client::new();

    // 组装header
    let mut headers = HeaderMap::new();
    headers.insert("Content-Type", "application/json".parse().unwrap());

    // 组装要提交的数据
    let mut data = HashMap::new();
    data.insert("user", "tangjz");
    data.insert("password", "dev-tang.com");

    // 发起post请求并返回
    Ok(client.post("https://httpbin.org/post").headers(headers).json(&data).send().await?.json::<HashMap<String, Value>>().await?)
}

#[tokio::main]
async fn main() {
    if let Ok(res) = post().await {
        println!("{:#?}", res);
    }
}

POST 请求比 GET 稍微复杂那么一点点。先看 use 引用,比 GET 请求多了两个 use,分别是 reqwest::header::HeaderMap、serde_json::value::Value,后面简称HeaderMap、Value。

HeaderMap 是用来组装 POST 请求时附加的 headers 数据。 Value 是 serde_json crate 中的,用来接收 POST 请求后返回的 JSON 数据。这点非常重要,在 GET 中接收 JSON 数据用的是 HashMap<String, String> ,在这里把 String 换成了 Value 是为了可以适用于多种类型,而不局限于String。

serde_json::value::Value支持的类列表如下图:

因为用到了serde_json,所以在 Cargo.toml 中要加入 serde_json。

[dependencies]
serde_json = "1.0"

4、最终完整代码

Cargo.toml

[dependencies]
reqwest = { version = "0.10", features = ["json"] }
tokio = { version = "0.2", features = ["full"] }
serde_json = "1.0"

main.rs

use std::collections::HashMap;
use reqwest::header::HeaderMap;
use serde_json::value::Value;


async fn get() -> Result<HashMap<String, String>, reqwest::Error>{
    Ok(reqwest::get("https://httpbin.org/ip").await?.json::<HashMap<String, String>>().await?)
}

async fn post() -> Result<HashMap<String, Value>, reqwest::Error>{
    // post 请求要创建client
    let client = reqwest::Client::new();

    // 组装header
    let mut headers = HeaderMap::new();
    headers.insert("Content-Type", "application/json".parse().unwrap());

    // 组装要提交的数据
    let mut data = HashMap::new();
    data.insert("user", "tangjz");
    data.insert("password", "dev-tang.com");

    // 发起post请求并返回
    Ok(client.post("https://httpbin.org/post").headers(headers).json(&data).send().await?.json::<HashMap<String, Value>>().await?)
}

#[tokio::main]
async fn main() {
    if let Ok(resp) = get().await {
        println!("{:#?}", resp);
    }

    if let Ok(res) = post().await {
        println!("{:#?}", res);
    }
}

本博客采用 知识共享署名-禁止演绎 4.0 国际许可协议 进行许可

本文标题:Rust使用 reqwest 发起 GET/POST 异步请求

本文地址:https://dev-tang.com/post/2020/09/rust-async-httpclient.html

推荐阅读