LoginSignup
1

More than 1 year has passed since last update.

posted at

updated at

Organization

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

目的

同時に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(())
}

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
What you can do with signing up
1