Batteries-included HTTP for Wyn. A thin, obvious layer over the native
Http builtins: request parsing, JSON/HTML/text responses, safe static
files, and HTML page building. Concurrency is the language's: spawn one
handler per request and every handler runs on the coroutine scheduler.
wyn pkg add web # resolves to github.com/wynlang/webimport web
fn handle(conn: int) {
// one coroutine per connection — serves keep-alive requests in a loop
while true {
var req = web.read_request(conn)
if req.len() == 0 { return }
route(req)
}
}
fn route(req: string) {
if web.is(req, "GET", "/") == 1 {
web.html(req, 200, web.page("Hello", "<h1>Hello from Wyn</h1>", ""))
} else if web.is(req, "GET", "/api/greet") == 1 {
var name = web.param(req, "name")
if name.len() == 0 { name = "world" }
var out = "{\"greeting\":\"hello, "
out = out + web.json_escape(name)
out = out + "\"}"
web.json(req, 200, out)
} else if web.is_under(req, "GET", "/static/") == 1 {
web.serve_static(req, "/static/", "public")
} else {
web.not_found(req)
}
}
fn main() {
var server = web.listen(8080)
println("http://localhost:8080")
while true {
var conn = web.accept(server)
if conn > 0 { spawn handle(conn) }
}
}
Server — listen(port) -> int, accept(server) -> int (blocks; returns the
connection fd to pass to your spawned handler), read_request(conn) -> string
(inside the handler; parks cooperatively — a slow client never stalls others).
Measured on the hello example (ab, macOS arm64): 22,000+ req/s with keep-alive, zero failed requests at 200 concurrent connections (~7,200 req/s connection-per-request).
Request — method(req), path(req) (query stripped), query(req),
param(req, name), body(req), fd(req), is(req, method, path),
is_under(req, method, prefix).
Responses — html/json/text(req, status, content), not_found(req),
method_not_allowed(req), bad_request(req, message) (message JSON-escaped),
redirect(req, location).
Static files — serve_static(req, prefix, dir): traversal-safe (..
rejected), MIME from extension via mime_type(path), index.html default.
Building output — page(title, body_html, extra_head) (complete styled
HTML5 page; title escaped), escape(s) (HTML), json_escape(s).
wyn testThe request is the runtime's packed METHOD|PATH|BODY|FD string; accessors
parse what they need. When cross-module struct support lands in the compiler,
this grows a real Request type without breaking the function surface.