HTTP server
Langoost has a built-in HTTP server. Call http.serve(port, handler) and each
incoming request runs your handler in its own isolated VM — a private stack
and output buffer per request, so concurrent requests never share mutable state.
A minimal server
The handler receives up to four arguments — method, path, query, body —
and returns a string:
import http
import strings
import json
fn handle(method: string, path: string, query: string, body: string): string {
if path == "/health" {
return "{\"status\": \"ok\"}"
}
if path == "/echo" && method == "POST" {
return body
}
if path == "/greet" {
let name = "World"
if strings.contains(query, "name=") {
let parts = strings.splitN(query, "name=", 2)
name = parts[1]
}
let data: json = {message: "Hello"}
return json.setString(data, "message", "Hello, " + name + "!")
}
return "404 Not Found"
}
http.serve(8080, handle)
Response format
- Plain string → HTTP
200with that body. - Status prefix → start the string with a 3-digit code and a space to set
the status:
"404 Not Found","500 Internal Server Error","201 " + json.stringify(resource). - Content-Type is detected automatically: responses starting with
{or[are sent asapplication/json; everything else astext/plain; charset=utf-8.
Isolation & shared state
Because each request runs in its own VM, there is no shared mutable state by
default — which is what makes requests safe to run concurrently. When you do
need to share data across requests, use the global key-value store in
runtime.core:
import runtime
runtime.core.share("visits", "0")
let n = toInt(runtime.core.fetch("visits"))
runtime.core.share("visits", toString(n + 1))
HTTP client
The same http module is also a client for talking to other services:
import http
let body = http.get("https://api.example.com/users")
let resp = http.request("GET", "https://api.example.com/me", "", [
"Authorization: Bearer my-token",
"Accept: application/json"
])
See the concurrency guide for background work and the
thread module.