Question
How can I make an HTTP request in Rust? I cannot find support for this in the standard library.
I only need to send a request and inspect the HTTP response status code; I do not need to parse the response body.
It would also be helpful to see how to safely URL-encode query parameters.
For example, the goal is something like:
// Pseudocode
let response = make_request("https://example.com/search?q=rust language");
println!("Status: {}", response.status());
Short Answer
By the end of this page, you will understand how HTTP requests are typically made in Rust, why the standard library does not include a full HTTP client, and how to use a crate such as reqwest to send requests, check status codes, and safely add URL-encoded query parameters.
Concept
Rust's standard library focuses on core building blocks such as strings, collections, file I/O, networking primitives, and concurrency. It does not provide a high-level HTTP client.
That means if you want to make HTTP requests in Rust, you usually use a community crate. The most common beginner-friendly choice is [reqwest], which provides a simple API for sending HTTP requests.
Why this matters
HTTP requests are used everywhere in real programs:
- calling APIs
- downloading files
- checking whether a service is online
- sending form data
- authenticating users
A good HTTP client should help you:
- build URLs safely
- send requests using methods like
GETandPOST - inspect status codes such as
200 OKor404 Not Found - handle network errors cleanly
Key idea
In Rust, the usual workflow is:
- Add an HTTP client crate to
Cargo.toml - Send a request
- Check the returned
Response - Read the status code or body if needed
For URL encoding, you should avoid manually concatenating strings when query values may contain spaces, &, ?, or other special characters. Instead, use helper methods that encode parameters correctly for you.
Mental Model
Think of Rust's standard library as a basic toolbox.
It gives you essentials like:
- a hammer
- a screwdriver
- measuring tape
But an HTTP client is more like a specialized power tool. It is extremely useful, but not part of the smallest core set of tools.
So when you need to talk to a website or API, you reach for an external crate like reqwest.
For query parameters, imagine writing an address on a package. If the address contains spaces or special symbols, you need to format it correctly so the delivery system understands it. URL encoding does that formatting for web addresses.
Syntax and Examples
The easiest way to make an HTTP request in Rust is with the reqwest crate.
Add the dependency
In Cargo.toml:
[dependencies]
reqwest = { version = "0.12", features = ["blocking"] }
The blocking feature is useful for simple scripts and beginner examples.
Simple GET request
use reqwest::blocking::get;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let response = get("https://httpbin.org/status/200")?;
println!("Status: {}", response.status());
Ok(())
}
What this does
get(...)sends a GET request- it returns a
Response
Step by Step Execution
Consider this example:
use reqwest::blocking::Client;
use std::error::Error;
fn main() -> Result<(), Box<dyn Error>> {
let client = Client::new();
let response = client
.get("https://httpbin.org/get")
.query(&[("q", "rust language")])
.send()?;
println!("Status: {}", response.status());
Ok(())
}
Here is what happens step by step:
Client::new()creates an HTTP client..get("https://httpbin.org/get")prepares a GET request..query(&[("q", "rust language")])adds a query parameter.- Rust passes the key
q - Rust passes the value
rust language reqwestURL-encodes the value safely
- Rust passes the key
Real World Use Cases
HTTP requests in Rust are common in many types of software.
API clients
A Rust service may call another API to fetch:
- user profiles
- payment status
- weather data
- shipping updates
Health checks
A monitoring script can send a request to a service endpoint and verify that it returns 200 OK.
Command-line tools
A CLI written in Rust might:
- test whether a URL is reachable
- verify a deployment endpoint
- query a web service
Data ingestion
A backend job can request data from a remote server, then process or store it.
Search and filtering
Applications often send query parameters such as:
?q=rust?page=2?sort=desc
Using a proper query builder avoids broken URLs and encoding bugs.
Real Codebase Usage
In real Rust codebases, developers usually avoid one-off string concatenation for URLs and instead use clients and helper methods.
Common patterns
Reuse a Client
Instead of calling a top-level get everywhere, many projects create a Client once and reuse it.
use reqwest::blocking::Client;
fn build_client() -> Client {
Client::new()
}
This keeps code organized and is often more efficient.
Check status explicitly
if response.status().is_success() {
println!("Request succeeded");
} else {
println!("Request failed with status: {}", response.status());
}
Guard clauses for errors
use reqwest::blocking::get;
use std::error::Error;
fn check_url(url: &) <(), < Error>> {
= (url)?;
!response.().() {
((, response.()).());
}
(())
}
Common Mistakes
Beginners often run into a few common problems when making HTTP requests in Rust.
1. Expecting HTTP support in the standard library
Rust's standard library does not include a high-level HTTP client.
Incorrect idea
// This kind of API does not exist in std
// let response = std::http::get("https://example.com");
Fix
Add a crate like reqwest in Cargo.toml.
2. Manually building query strings unsafely
Problem
let term = "rust language & web";
let url = format!("https://example.com/search?q={}", term);
This can produce an invalid or misleading URL because special characters are not encoded.
Better
let response = client
.get("https://example.com/search")
.query(&[("q", "rust language & web")])
.send()?;
Comparisons
Here are some useful comparisons related to making HTTP requests in Rust.
| Option | Best for | Pros | Cons |
|---|---|---|---|
std library only | Low-level networking | No extra dependencies | No high-level HTTP client |
reqwest::blocking | Simple scripts, beginner examples | Easy to read, straightforward | Blocks the current thread |
async reqwest | Async apps and servers | Works well in async systems | Slightly more setup |
| Manual URL string building | Very simple fixed URLs | Quick for tiny cases | Error-prone for query parameters |
.query(...) helper |
Cheat Sheet
[dependencies]
reqwest = { version = "0.12", features = ["blocking"] }
Simple request
let response = reqwest::blocking::get("https://example.com")?;
println!("{}", response.status());
Reusable client
let client = reqwest::blocking::Client::new();
let response = client.get("https://example.com").send()?;
Add query parameters safely
let response = client
.get("https://example.com/search")
.query(&[("q", "rust language"), ("page", "1")])
.send()?;
Check status
FAQ
Why doesn't Rust's standard library include HTTP requests?
Rust keeps the standard library relatively small and focused on core features. High-level HTTP support is usually provided by crates such as reqwest.
What crate should I use for HTTP requests in Rust?
For most beginners and many real projects, reqwest is the most common choice because it is ergonomic and well documented.
How do I check only the HTTP status code in Rust?
Send the request, get the Response, and call response.status().
How do I URL-encode query parameters in Rust?
The safest option is to use .query(...) with reqwest::Client, which encodes parameters for you.
Is 404 Not Found returned as a Rust error?
Usually no. A 404 is often a valid HTTP response, so you need to inspect the status code yourself.
Should I use blocking or async reqwest?
Use blocking for simple scripts and learning. Use async reqwest when working inside an async application.
Mini Project
Description
Build a small Rust command-line program that sends an HTTP GET request to a search endpoint, includes user-provided query parameters safely, and prints the HTTP status code. This demonstrates the most common beginner workflow: create a client, attach query parameters, send a request, and inspect the response.
Goal
Create a Rust program that sends a GET request with encoded query parameters and reports whether the request succeeded based on the HTTP status code.
Requirements
- Create a Rust project that uses
reqwestwith theblockingfeature. - Send a GET request to
https://httpbin.org/get. - Add at least two query parameters using a safe query builder.
- Print the full HTTP status code.
- Print a success or failure message based on the status.
Keep learning
Related questions
Accessing Cargo Package Metadata in Rust
Learn how to read Cargo package metadata like version, name, and authors in Rust using compile-time environment macros.
Associated Types vs Generic Type Parameters in Rust: When to Use Each
Learn when to use associated types vs generic parameters in Rust traits, with clear rules, examples, and practical API design advice.
Can a Struct Extend Another Struct in Rust? Composition vs Inheritance
Learn how Rust handles struct reuse without inheritance, using composition, traits, and wrapper structs with practical examples.