HTTP: Calling an API
● Intermediate3 min
http.get and http.post call a URL and give its Response: the status, the headers and the body.
const page = try http.get("https://example.com/")
print(page.status)
print(page.body.text() ?? "")When a call can't work, the error says why. A refused connection and an address that isn't HTTP:
use std.http
use std.net
fn main() {
for url in ["http://127.0.0.1:1/", "ftp://example.com/file"] {
const page = http.get(url) catch e => match e {
HttpError.BadUrl(u) => {
print("not an http address: {u}")
return
}
HttpError.Network(cause) => {
print("couldn't connect: {cause}")
continue
}
_ => {
print("failed: {e}")
continue
}
}
print(page.status)
}
}The program ran and printed:
kavach run errors.kav
couldn't connect: Refused(address: "127.0.0.1:1")not an http address: ftp://example.com/file
Network(…): the connection failed, with theNetErrorinside.BadUrl: not anhttp://orhttps://address.Status(code): the server answered, but not with success (from the JSON helpers).BadMessage,BadJson: the answer was broken, or not the JSON you asked for.
Every network wait has a time limit, so a server that stops answering can't hang your program: see Timeouts.
Any method, any headers
http.request(method, url, headers:, body:) sends any method with the headers you give: a PUT or DELETE, a bearer token, basic auth, if-none-match:
use std.http
use std.net
fn echo(r: Request) -> Response {
const auth = r.header("authorization") ?? "none"
http.text(200, "{r.method} {r.path}, auth: {auth}, body: {r.body.text() ?? ""}")
}
fn main() ! Error {
const listener = try net.listen("127.0.0.1:0")
const _server = spawn http.serve(listener, echo)
const url = "http://{listener.address()}/orders/7"
const token = Header(name: "authorization", value: "Bearer test-token")
const put = try http.request("PUT", url, headers: [token], body: "paid".bytes())
print(put.body.text() ?? "")
const gone = try http.request("DELETE", url)
print(gone.body.text() ?? "")
}The program ran and printed:
kavach run request.kav
PUT /orders/7, auth: Bearer test-token, body: paidDELETE /orders/7, auth: none, body:
host,content-lengthandconnectionare the client's own, so ones you give are left out.- It uses HTTP/2 when the server offers it with TLS, and HTTP/1.1 otherwise.
- On a session,
s.request(method, path, …)does the same on its connection.