使用 Rust 调用 REST API
JSON : Placeholder
JSON : Placeholder (https://jsonplaceholder.typicode.com/) 是一个用于测试的 REST API 网站。
以下使用 Rust 调用该网站的 REST API,获取字符串以及 JSON 数据。
- GET /posts/1
- GET /posts
- POST /posts
- PUT /posts/1
- DELETE /posts/1
所有 GET API 都返回JSON数据,格式(JSON-Schema)如下:
{
"type":"object",
"properties": {
"userId": {"type" : "integer"},
"id": {"type" : "integer"},
"title": {"type" : "string"},
"body": {"type" : "string"}
}
}
Rust
Cargo.toml
[package]
...
[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"
reqwest = { version = "0.10.8", features = ["json"] }
tokio = { version = "0.2.22", features = ["rt-threaded", "macros"] }
main.rust
use std::error::Error;
use serde::{Deserialize, Serialize};
#[derive(Serialize, Deserialize, Debug, Clone)]
struct Post {
#[serde(rename(serialize = "userId", deserialize = "userId"))]
user_id: i32,
id: i32,
title: String,
body: String,
}
const BASE_URL: &str = "http://jsonplaceholder.typicode.com/";
async fn get_post_as_string() -> Result<String, Box<dyn Error>> {
let url = format!("{}posts/1", BASE_URL);
let s = reqwest::get(&url).await?.text().await?;
Ok(s)
}
async fn get_post_as_json() -> Result<Post, Box<dyn Error>> {
let url = format!("{}posts/1", BASE_URL);
let v: Post = reqwest::get(&url).await?.json().await?;
Ok(v)
}
async fn get_posts() -> Result<Vec<Post>, Box<dyn Error>> {
let url = format!("{}posts", BASE_URL);
let v: Vec<Post> = reqwest::get(&url).await?.json().await?;
let v = v[0..2].to_vec();
Ok(v)
}
async fn create_post() -> Result<String, Box<dyn Error>> {
let url = format!("{}posts", BASE_URL);
let o = Post {
user_id: 1,
id: 0,
title: "test title".to_string(),
body: "test body".to_string()
};
let s = reqwest::Client::new().post(&url).body(serde_json::to_string(&o)?).send().await?.text().await?;
Ok(s)
}
async fn update_post() -> Result<String, Box<dyn Error>> {
let url = format!("{}posts/1", BASE_URL);
let o = Post {
user_id: 1,
id: 1,
title: "test title".to_string(),
body: "test body".to_string()
};
let s = reqwest::Client::new().put(&url).body(serde_json::to_string(&o)?).send().await?.text().await?;
Ok(s)
}
async fn delete_post() -> Result<String, Box<dyn Error>> {
let url = format!("{}posts/1", BASE_URL);
let s = reqwest::Client::new().delete(&url).send().await?.text().await?;
Ok(s)
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
println!("{}", get_post_as_string().await?);
println!("{:?}", get_post_as_json().await?);
println!("{:?}", get_posts().await?);
println!("{}", create_post().await?);
println!("{}", update_post().await?);
println!("{}", delete_post().await?);
Ok(())
}
- get_post_as_string 函数取出第1个Post,返回字符串
- get_post_as_json 函数取出第1个Post,返回Post对象
- get_posts 函数取出前2个Post,返回2个Post对象
- create_post 函数创建1个Post,返回字符串
- update_post 函数更新第1个Post,返回字符串
- delete_post 函数删除第1个Post,返回字符串
输出
程序执行后的输出为
{
"userId": 1,
"id": 1,
"title": "sunt aut facere repellat provident occaecati excepturi optio reprehenderit",
"body": "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto"
}
Post { user_id: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }
[Post { user_id: 1, id: 1, title: "sunt aut facere repellat provident occaecati excepturi optio reprehenderit", body: "quia et suscipit\nsuscipit recusandae consequuntur expedita et cum\nreprehenderit molestiae ut ut quas totam\nnostrum rerum est autem sunt rem eveniet architecto" }, Post { user_id: 1, id: 2, title: "qui est esse", body: "est rerum tempore vitae\nsequi sint nihil reprehenderit dolor beatae ea dolores neque\nfugiat blanditiis voluptate porro vel nihil molestiae ut reiciendis\nqui aperiam non debitis possimus qui neque nisi nulla" }]
{
"id": 101
}
{
"id": 1
}
{}