POLYTONE — the AI-native programming language

Guide

Serving HTTP

Since Sprints 350–351 a program serves HTTP with a plain handler function.

api.pt
import http

fn handle(req: http.Request) -> http.Response:
    match http.route("/hello/:name", req.path()):
        case Some(params):
            return http.text(200, "hello, {params.get("name").unwrap_or("?")}")
        case None:
            return http.text(404, "no route {req.path()}")

fn main(server: HttpServer) -> Void:
    print("answered {server.serve(8080, handle)}")

test "the handler is a plain function":
    assert handle(http.get("/hello/ada")).text() == Some("hello, ada")
    assert handle(http.get("/nope")).status.code == 404

test "a scripted server answers every request":
    assert mock_server([http.get("/hello/x"), http.get("/y")]).serve(8080, handle) == 2

serve(port, handler) hands every request to a fn(http.Request) -> http.Response and returns how many it answered. Under ptc run it binds 127.0.0.1 and answers one request at a time (timeouts, size limits, 405 for unknown methods, no response splitting); POLYTONE_SERVE_LIMIT=n stops it after n requests. The stdlib http carries text/html/json responses, req.path(), req.query(name) and route patterns with :params; examples/calc_api.pt is a complete service.