LoginSignup
3
1

More than 3 years have passed since last update.

RustでTwitterAPIを非同期に呼んでみる

Last updated at Posted at 2020-12-04

目的

同時にTwitterAPIを呼んでみました。
Stackoverflowのカービーの回答を参考にしました。
How can I perform parallel asynchronous HTTP GET requests with reqwest?
適当にピックアップしたツイートIDを非同期に取得してみます。

プログラム

Cargo.toml
[package]
name = "tw"
version = "0.1.0"
edition = "2018"

[dependencies]
anyhow = "1.0.34"
futures = "0.3.8"
tokio = { version = "0.2.23", features = ["macros"] }
twapi-reqwest = "0.1.3"
main.rs
use anyhow::Result;
use futures::{stream, StreamExt};
use std::env;
use twapi_reqwest::*;

const PARALLEL_REQUESTS: usize = 10;

#[tokio::main]
async fn main() -> Result<()> {
    let consumer_key = env::var("CONSUMER_KEY").unwrap();
    let consumer_secret = env::var("CONSUMER_SECRET").unwrap();
    let access_key = env::var("ACCESS_KEY").unwrap();
    let access_secret = env::var("ACCESS_SECRET").unwrap();

    let ids: Vec<i64> = vec![
        1331969354494164996,
        1332080137202847744,
        1331999525309857793,
        1332074865323479041,
        1331960277269508096,
        1332078310726062080,
        1331945614947414016,
        1331938585126137856,
        1332067717176643584,
    ];

    let retweet_counts = stream::iter(ids)
        .map(|id| {
            let consumer_key = consumer_key.clone();
            let consumer_secret = consumer_secret.clone();
            let access_key = access_key.clone();
            let access_secret = access_secret.clone();
            tokio::spawn(async move {
                let url = "https://api.twitter.com/1.1/statuses/show.json";
                let id: &str = &id.to_string();
                let query_options = vec![("id", id)];
                v1::get(
                    url,
                    &query_options,
                    &consumer_key,
                    &consumer_secret,
                    &access_key,
                    &access_secret,
                )
                .await?
                .json::<serde_json::Value>()
                .await
                .and_then(|json| Ok(json["retweet_count"].as_i64().unwrap_or(0)))
            })
        })
        .buffer_unordered(PARALLEL_REQUESTS);

    retweet_counts
        .for_each(|retweet_count| async move {
            match retweet_count {
                Ok(Ok(retweet_count)) => println!("retweet_count {}", retweet_count),
                Ok(Err(e)) => eprintln!("Got a twapi::Error: {}", e),
                Err(e) => eprintln!("Got a tokio::JoinError: {}", e),
            }
        })
        .await;

    Ok(())
}
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1