4. Making Requests¶
A method call like client.get(path) returns a request_builder_t, onto which you chain
query/headers/body, then send it with submit/fetch/download.
HTTP Methods¶
client.get ("/games/g-20260611-0042");
client.post ("/games");
client.put ("/games/g-20260611-0042/settings");
client.patch ("/games/g-20260611-0042"); // partial update
client.delete_ ("/games/g-20260611-0042"); // delete is a keyword, hence delete_
client.head ("/replays/r-99182.bin"); // headers only (no body)
client.options ("/games"); // query the allowed methods
A HEAD response has an empty body — only status and headers come back.
auto head = client.head ("/replays/r-99182.bin").submit_raw ().result ();
if (head && head.value ().status == 200) {
const auto size = head.value ().headers.at ("content-length");
}
The path must start with /, or it throws request_protocol_error.
Query Parameters¶
query(name, value) handles percent-encoding automatically. Use this instead of assembling the
string into the path directly.
auto open_games = client.get ("/games")
.query ("status", "open")
.query ("mode", "ranked 2v2") // space → %20
.query ("region", "kr&jp") // & → %26
.fetch<game_list_t> ();
// actual target: /games?status=open&mode=ranked%202v2®ion=kr%26jp
If the path already has a ?, subsequent parameters are appended with &.
Headers¶
The client-level default_header (every request) and the request-level header (this request
only) are combined. For the same name, the request side wins.
auto client = zlink::http_client::client_t::create ("https://game-api.example.internal")
.default_header ("x-service-name", "matchmaker")
.build ();
client.post ("/games")
.header ("x-idempotency-key", "9f2c1a77-58be-4d10-8d7e-3b1f0a44c2e9")
.body (create_game_http_req_t{.game_name = "ranked-match-0611"})
.submit<create_game_http_res_t> ();
Per-Request Timeout¶
You can override the client's default timeout for a specific request. Use this for long-running operations (report generation, etc.) or a health probe that should give up quickly.
// The client default is 3 seconds; report generation alone allows 30
auto report = client.post ("/reports/season-2026q2")
.timeout (std::chrono::seconds (30))
.submit_raw ()
.result ();
// The health probe fails if there's no answer within 200ms
auto ready = client.get ("/ready")
.timeout (std::chrono::milliseconds (200))
.submit_raw ()
.result ();
A timeout exceeded is reported as framework_error_kind_t::timeout (retriable) —
13. Error Handling.