News API API in Rust
News API API in Rust
This guide shows you how to integrate the News API into your Rust application. Headlines and articles from 80,000+ worldwide news sources.
Prerequisites
- Rust installed on your system
- An News API API key (sign up at https://newsapi.org)
- Basic familiarity with HTTP APIs
Installation
cargo add reqwest --features json
cargo add tokio --features full
Basic Usage
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = env::var("API_KEY").unwrap_or_else(|_| "YOUR_API_KEY".to_string());
let base_url = "https://api.newsapi.org";
let url = format!("{}/v1/resources", base_url);
let client = reqwest::Client::new();
let resp = client
.get(&url)
.bearer_auth(&api_key)
.header("Content-Type", "application/json")
.send()
.await?;
println!("Status: {}", resp.status());
let body = resp.text().await?;
println!("{}", body);
Ok(())
}
Error Handling
use std::time::Duration;
use std::env;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = env::var("API_KEY").unwrap_or_else(|_| "YOUR_API_KEY".to_string());
let base_url = "https://api.newsapi.org";
let client = reqwest::Client::builder()
.timeout(Duration::from_secs(30))
.build()?;
let mut attempt = 0;
let max_retries = 3;
loop {
let resp = client
.get(format!("{}/v1/resources", base_url))
.bearer_auth(&api_key)
.send()
.await?;
if resp.status().as_u16() == 429 {
println!("Rate limited. Waiting 60s...");
tokio::time::sleep(Duration::from_secs(60)).await;
continue;
}
if resp.status().is_success() {
let body = resp.text().await?;
println!("{}", body);
return Ok(());
}
attempt += 1;
if attempt >= max_retries {
return Err(format!("HTTP {}", resp.status()).into());
}
tokio::time::sleep(Duration::from_secs(2u64.pow(attempt))).await;
}
}
Advanced Usage
use std::env;
use reqwest::{Client, Method};
use std::error::Error;
pub struct NewsapiClient {
client: Client,
api_key: String,
base_url: String,
}
impl NewsapiClient {
pub fn new(api_key: String, base_url: String) -> Self {
Self {
client: Client::new(),
api_key,
base_url: base_url.trim_end_matches('/').to_string(),
}
}
pub async fn request(&self, method: Method, path: &str) -> Result<String, Box<dyn Error>> {
let url = format!("{}/v1{}", self.base_url, path);
let resp = self.client
.request(method, &url)
.bearer_auth(&self.api_key)
.header("Content-Type", "application/json")
.send()
.await?;
if !resp.status().is_success() {
return Err(format!("API Error: HTTP {}", resp.status()).into());
}
Ok(resp.text().await?)
}
pub async fn list_resources(&self) -> Result<String, Box<dyn Error>> {
self.request(Method::GET, "/resources").await
}
}
#[tokio::main]
async fn main() -> Result<(), Box<dyn Error>> {
let client = NewsapiClient::new(
env::var("API_KEY")?,
"https://api.newsapi.org".to_string(),
);
let resources = client.list_resources().await?;
println!("{}", resources);
Ok(())
}
Best Practices
- Store your API key in an environment variable, never in source code
- Implement retry logic with exponential backoff for 429 and 5xx errors
- Set reasonable timeouts (10-30 seconds) for all API calls
- Log request IDs from response headers for debugging
- Cache responses where appropriate to reduce API calls