Expand description
An HTTP client for calling other services (payment gateways, shipping rates, webhooks you send), with timeouts, retries and a fake for tests.
#[derive(serde::Deserialize)]
struct Rates { eur: f64 }
let rates: Rates = state
.http
.get("https://api.example.com/rates")
.query(&[("base", "USD")])
.bearer(token)
.timeout(Duration::from_secs(5))
.retry(3, Duration::from_millis(200)) // on connection errors, 429 and 5xx
.send()
.await?
.error_for_status()? // a 4xx/5xx becomes an error
.json()?;
let created = state
.http
.post("https://api.example.com/orders")
.json(&renox::serde_json::json!({ "total": 7_500 }))
.send()
.await?;
assert!(created.ok());In tests, TestApp::fake_http
answers requests instead of the network and records them:
use renox::http::FakeResponse;
let http = app.fake_http();
http.on("https://api.example.com/rates*", FakeResponse::json(200, json!({ "eur": 0.92 })));
http.on("POST https://api.example.com/orders", FakeResponse::status(503)); // then…
http.on("POST https://api.example.com/orders", FakeResponse::json(201, json!({ "id": 7 })));
// … exercise the app …
http.assert_sent(|r| r.method == "POST" && r.body.contains("7500"));Requests with no fake fail while faking, so a test never reaches the
network by accident. Real requests need the http feature (on by
default).
Structs§
- Fake
Http - The fake behind
state.httpin tests; fromHttp::fakeorTestApp::fake_http. - Fake
Response - A canned answer for
FakeHttp::on. - Http
- The app’s HTTP client (
state.http). - Request
- A request being built; send it with
Request::send. - Response
- A response, read whole.
- Sent
Request - A request the fake received.