HTTP: JSON over HTTP
● Intermediate3 min
post_json and get_json send and read your own types; read_json and json_response do it on the server. The type is the contract.
use std.http
use std.json
use std.net
type Order {
id: Int
item: String
}
fn orders(r: Request) -> Response {
const wanted = http.read_json<Order>(r) catch _ => return http.text(400, "not an order")
http.json_response(200, json.of(Order(id: wanted.id, item: "{wanted.item}, packed")))
}
fn main() ! Error {
const listener = try net.listen("127.0.0.1:0")
const _server = spawn http.serve(listener, orders)
const url = "http://{listener.address()}/orders"
const packed = try http.post_json<Order>(url, json.of(Order(id: 7, item: "pen")))
print(packed.item)
}The program ran and printed:
kavach run json.kav
pen, packedThe client and the server share Order. A body that isn't an Order is refused with status 400 on the server, and with BadJson on the client. A status that isn't a success fails with Status(code):
use std.http
use std.net
type Order {
id: Int
}
fn shop(r: Request) -> Response {
if r.path == "/orders/7" {
return http.text(200, "\{\"id\": 7}")
}
http.text(404, "no such order")
}
fn main() ! Error {
const listener = try net.listen("127.0.0.1:0")
const _server = spawn http.serve(listener, shop)
const base = "http://{listener.address()}"
const found = try http.get_json<Order>("{base}/orders/7")
print("found {found.id}")
const missing = http.get_json<Order>("{base}/orders/8") catch e => {
print("failed: {e}")
return
}
print(missing.id)
}The program ran and printed:
kavach run status.kav
found 7failed: Status(code: 404)