Synsema docsENES

Build a REST API

A full CRUD API — routes, auth, validation, pagination, a real database — in one file, with the production HTTP server built in. No framework, no ASGI server, no requirements.txt.

The whole thing

require serve(8080)
require db("./store.db")

task check_token(req)
    give header_of(req, "authorization") == "Bearer secret"   -- your real check here

serve on 8080
    auth with check_token

    route "GET /products"
        give paged("SELECT id, name, price FROM products ORDER BY id")   -- paginated + total

    route "GET /products/:id"
        let rows be sql("SELECT * FROM products WHERE id = ?", [params.id])
        give when length(rows) == 0 then not_found("no such product") otherwise rows[0]

    route "POST /products" requires auth
        expect body {name: text, price: number}      -- 400 automatically if it doesn't match
        let b be json of request
        sql_exec("INSERT INTO products (name, price) VALUES (?, ?)", [b["name"], b["price"]])
        give created(b)

    route "DELETE /products/:id" requires auth
        sql_exec("DELETE FROM products WHERE id = ?", [params.id])
        give ok({"deleted": params.id})

Run it: synsema serve api.syn. That's a production server — async, true multi-core, a single static binary with zero runtime.

What you got for free

serve.syn
-- Doc example: the serve response contract. Helpers return {status, value}; the
-- runtime renders them. (A real `serve on` block doesn't terminate, so the doctest
-- asserts the response shapes the handlers give — see the prose for a full server.)
intent: "doc example: serve response contract"

print("ok → " + text(status of ok({"a": 1})) + ",  fail(400) → " + text(status of fail(400, "bad")))

test "uniform response helpers carry a status + value"
    assert_eq(status of ok({"a": 1}), 200)
    assert_eq(status of created({"id": 1}), 201)
    assert_eq(status of fail(400, "bad input"), 400)
    assert_eq(status of not_found("missing"), 404)
    assert_eq((value of fail(400, "bad input"))["error"], "bad input")

vs. FastAPI

No framework to install, no Pydantic models, no Uvicorn, no requirements.txtone binary, one file. Validation and auth are language keywords, not decorators you wire up by hand. And it's secure by default and deployed with one flag. See HTTP server for the full route/SSE/CORS reference and Frontend to also serve HTML.