
TypedClients.pudu
Pudu62 lines2.7 KB
1/** @Examples.TypedClients.Program — a typed client reading and writing JSON values */2module TypedClients34import Std.Concurrent as Concurrent5import Std.Http.Server.Reply as Reply6import Std.Http.Server.Route as Route7import Std.Http.Server as Server8import Std.Io as Io9import Std.Json as Json10import Std.Option as Option11import PuduLangHttpClient.Client as Client12import PuduLangHttpClient.Client.Json as JsonClient13import PuduLangHttpClient.Factory.Builder as Builder14import PuduLangHttpClient.Factory as Factory15import PuduLangHttpClient as HttpClient16import PuduLangHttpClient.Response as Response1718/** @Examples.TypedClients.Todo — one item, written and read through derived implementations */19type Todo = { id: Int, title: Str, done: Bool } derives Json.Encode, Json.Decode2021/** @Examples.TypedClients.Todos — a typed client: the operations of one remote service */22type Todos = { client: Client.Client }232425fn find(todos: &Todos, id: Int) -> HttpClient.Outcome[Todo] { JsonClient.getFromJson(&todos.client, "todos/" + show(id)) }262728fn add(todos: &Todos, todo: &Todo) -> HttpClient.Outcome[Todo] {29 let response = Response.ensureSuccess(JsonClient.postAsJson(&todos.client, "todos", todo) ?) ?30 Response.readAs(&response)31}323334fn serve() -> (Server.Running, Str) {35 let running = match Server.start("127.0.0.1", 0) {36 case Ok(found) => found37 case Err(problem) => panic(show(problem))38 }39 let server = Server.server(&Route.routing(&[40 Route.get("/todos/:id", |request: Route.Request| Reply.json(200, "\{\"id\":" + Option.unwrapOr(Route.param(&request, "id"), "0") + ",\"title\":\"water the plants\",\"done\":false\}")),41 Route.post("/todos", |request: Route.Request| Reply.json(201, Route.body(&request)))42 ]))43 let _serving = Concurrent.start(fn() -> () { let _ran = Server.run(&server, &running, 0) })44 (running, "http://127.0.0.1:" + show(Server.portOf(&running)) + "/")45}464748fn main() -> Int {49 let (running, base) = serve()50 let factory = match Factory.build([Builder.named("todos").withBaseAddress(base)]) {51 case Ok(built) => built52 case Err(invalid) => panic(Factory.explain(&invalid))53 }54 let todos = Factory.typed(&factory, "todos", |client: Client.Client| Todos{client: client})55 let found = find(&todos, 7)56 let added = add(&todos, &Todo{id: 8, title: "write the docs", done: true})57 let _said = Io.writeLine(show(found) + "\n" + show(added))58 Factory.dispose(&factory)59 let _stopped = Server.stop(&running)60 if found == Ok(Todo{id: 7, title: "water the plants", done: false}) && added == Ok(Todo{id: 8, title: "write the docs", done: true}) { 0 } else { 1 }61}62