Reputation: 3
I just want to get a JSON from the following URL.
So I used this code:
extern crate reqwest;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let res = reqwest::Client::new()
.get("https://api.github.com/users/octocat")
.send()?
.text()?;
println!("{}", res);
Ok(())
}
But I don't know how to solve the error :
error[E0277]: the `?` operator can only be applied to values that implement `std::ops::Try`
--> src\main.rs:19:15
|
19 | let res = reqwest::Client::new()
| _______________^
20 | | .get("https://api.github.com/users/octocat")
21 | | .send()?
| |________________^ the `?` operator cannot be applied to type `impl std::future::Future`
|
= help: the trait `std::ops::Try` is not implemented for `impl std::future::Future`
= note: required by `std::ops::Try::into_result`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `Desktop`.
but I can also obtain what I want with a simple
curl https://api.github.com/users/octocat
I've tried to add use std::ops::Try;
but it doesn't work better.
Upvotes: 0
Views: 1232
Reputation: 13618
The reqwest
crate uprovides an asynchronous api by default. Therefore you have to .await
before handling the error with the ?
operator. You also have to use an async runtime, such as tokio
:
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::Client::new()
.get("https://api.github.com/users/octocat")
.send()
.await?
.json::<std::collections::HashMap<String, String>>()
.await?;
println!("{:#?}", resp);
Ok(())
}
Note that to use convert the response to json as shown above, you must enable the json
feature in your Cargo.toml
:
reqwest = { version = "0.10.8", features = ["json"] }
If you don't want to use an async runtime, you can enable the blocking reqwest
client:
[dependencies]
reqwest = { version = "0.10", features = ["blocking", "json"] }
And use it like so:
fn main() -> Result<(), Box<dyn std::error::Error>> {
let resp = reqwest::blocking::Client::new()
.get("https://api.github.com/users/octocat")
.send()?
.json::<std::collections::HashMap<String, String>>()?;
println!("{:#?}", resp);
Ok(())
}
Github's api requires a couple other config options. Here is a minimal working example with reqwest and the github api:
use reqwest::header::{HeaderMap, HeaderValue, USER_AGENT};
use serde::{Deserialize};
fn main() -> Result<(), Box<dyn std::error::Error>> {
let mut headers = HeaderMap::new();
// add the user-agent header required by github
headers.insert(USER_AGENT, HeaderValue::from_static("reqwest"));
let resp = reqwest::blocking::Client::new()
.get("https://api.github.com/users/octocat")
.headers(headers)
.send()?
.json::<GithubUser>()?;
println!("{:#?}", resp);
Ok(())
}
// Note that there are many other fields
// that are not included for this example
#[derive(Deserialize, Debug)]
pub struct GithubUser {
login: String,
id: usize,
url: String,
#[serde(rename = "type")]
ty: String,
name: String,
followers: usize
}
Upvotes: 4