ATL-S syntax (5 minutes)
Write HTTP apps in short .atl. Sugar expands to the same runtime as classic
forms; older verbose styles still work.
Hello route
module app
get "/hello" {
def hello(req) {
return json({ message: "hi" })
}
}
fn main() -> Int {
return 0
}
atlantus check --path .
Route blocks
get "/users" { def index(req) { return json(list()) } }
get "/users/{id}" { def show(req) { return json(get_one(req.param("id"))) } }
post "/users" { def create(req) { return json(create(req.json()), 201) } }
put "/users/{id}" { def update(req) { return json(update(req.param("id"), req.json())) } }
delete "/users/{id}" { def destroy(req) {
if delete_one(req.param("id")) {
return status(204)
}
return json({ error: "not_found" }, 404)
}}
- One
def/fnper block - Method + path become HTTP routes
- Untyped
reqis the request; omitted return is a response
def and fn
def add(a: Int, b: Int) -> Int {
return a + b
}
fn add(a: Int, b: Int) -> Int {
return a + b
}
JSON responses
| Write this | Means this |
|---|---|
json(body) / ok(body) | HTTP 200 + JSON body |
json(body, 201) / created(body) | HTTP 201 + JSON body |
status(204) / no_content() | Status only |
Request helpers
| Write this | Means this |
|---|---|
req.param("id") | Path param {id} |
req.json() | Parsed JSON body |
req.header("authorization") | Header value |
req.method() / req.path() | Method / path |
Elegant handlers
Short status + early-exit sugar (desugars to the same natives as above):
| Write this | Means this |
|---|---|
not_found(msg?) | 404 error envelope |
unauthorized / forbidden / bad_request | 401 / 403 / 400 |
unprocessable(msg_or_fields?) | 422 validation_failed |
let x = require_found(e, msg?) | value or 404 |
let x = require_json(req) | body or 422 |
let x = require_auth(req) | user id or 401 |
require_fields(map, ["a","b"]) | 422 if missing field |
get "/users/{id}" {
def show(req) {
let user = require_found(db_get("users", req.param("id")), "not found")
return ok(user)
}
}
post "/users" {
def create(req) {
let body = require_json(req)
require_fields(body, ["name"])
return created(body)
}
}
Null checks with none
let user = find(id)
if user is none {
return not_found()
}
return ok(user)
Control flow
if n > 0 {
return ok({ ok: true })
} else if n == 0 {
return ok({ ok: "zero" })
} else {
return bad_request("n must be >= 0")
}
Maps and arrays
let user = { "name": "Ada", "id": 1 }
let tags = ["atl", "web"]
Next: Language overview · HTTP & JSON.