URL shortener: POST a long URL, get a short code; GET the code redirects
Base36 code derived from a monotonic id. Hit count tracked per code. curl -X POST localhost:8080/shorten -d '{"url":"https://soma.dev"}' curl -i localhost:8080/r/<code>
A Soma program from the web part of the verified corpus: 75 lines, cells Shortener, ShortenerTest. It passes soma check with soma 3.2.4.
How it is built
The cell Shortener declares 4 signals in its face: request(method: String, path: String, body: String) -> Map, shorten(url: String) -> Map, resolve(code: String) -> String and stats(code: String) -> Map; keeps 2 memory slots: urls (Map<String, String>, persistent and consistent) and hits (Map<String, Int>, persistent and consistent). Handlers: shorten (line 33), resolve (line 40), stats (line 47) and request (line 52). Private helpers: _encode.
The file also holds 1 test cell (ShortenerTest) with 5 assertions, run by soma test.
The source
soma.toml
[package]
name = "web-corpus"
version = "0.1.0"
entry = "todo_state.cell"
[verify]
cells = ["TodoService"]
deadlock_free = true
eventually = ["Done", "Cancelled"]url_shortener.cell
// URL shortener: POST a long URL, get a short code; GET the code redirects.
// Base36 code derived from a monotonic id. Hit count tracked per code.
// curl -X POST localhost:8080/shorten -d '{"url":"https://soma.dev"}'
// curl -i localhost:8080/r/<code>
cell Shortener {
face {
signal request(method: String, path: String, body: String) -> Map
signal shorten(url: String) -> Map
signal resolve(code: String) -> String
signal stats(code: String) -> Map
promise all_persistent
}
memory {
urls: Map<String, String> [persistent, consistent]
hits: Map<String, Int> [persistent, consistent]
}
on _encode(n: Int) {
let alpha = "0123456789abcdefghijklmnopqrstuvwxyz"
if n == 0 { return "0" }
let s = ""
let x = n
while x > 0 {
let d = x - floor(x / 36) * 36
s = concat(alpha[d], s)
x = floor(x / 36)
}
return s
}
on shorten(url: String) {
let code = _encode(next_id())
urls.set(code, url)
hits.set(code, 0)
return map("code", code, "url", url)
}
on resolve(code: String) {
let url = urls.get(code)
if url == () { return "" }
hits.set(code, hits.get(code) + 1)
return url
}
on stats(code: String) {
if urls.get(code) == () { return response(404, map("error", "unknown code")) }
return map("code", code, "url", urls.get(code), "hits", hits.get(code))
}
on request(method: String, path: String, body: String) {
let req = map("method", method, "path", path)
match req {
{method: "POST", path: "/shorten"} -> shorten(from_json(body).url)
{method: "GET", path: "/r/" + code} -> {
let url = resolve(code)
if url == "" { response(404, map("error", "unknown code")) } else { redirect(url) }
}
{method: "GET", path: "/stats/" + code} -> stats(code)
_ -> response(404, map("error", "no route"))
}
}
}
cell test ShortenerTest {
rules {
assert _encode(0) == "0"
assert _encode(35) == "z"
assert _encode(36) == "10"
assert shorten("https://soma.dev").url == "https://soma.dev"
assert resolve(shorten("https://x.io").code) == "https://x.io"
}
}What the toolchain says
$ soma check url_shortener.cell
warning: `s` grows by concatenation inside a loop — each step copies the whole value, so the loop is quadratic (8 MB took 32 s, a list + join() 30 ms): push the pieces to a List and `join(parts, "")` once
--> url_shortener.cell:27:13
|
27 | s = concat(alpha[d], s)
| ^
✓ 1 warning(s), no errors.$ soma test url_shortener.cell
test ShortenerTest ...
✓ assert _encode(0) == "0"
✓ assert _encode(35) == "z"
✓ assert _encode(36) == "10"
✓ assert shorten("https://soma.dev").url == "https://soma.dev"
✓ assert resolve(shorten("https://x.io").code) == "https://x.io"
5 tests: 5 passed, 0 failed$ soma verify url_shortener.cell
Verifying url_shortener.cell...
note: soma.toml [verify] cells names 'TodoService', which this file does not define — its properties are not checked here
Shortener/termination:
⚠ handler `_encode`: while-loop without provable termination bound (write `while [loop_bound(N)] cond { … }`, or a for-loop over a bounded range)
⚠ `shorten` calls `Shortener._encode`, which may not terminate
⚠ `request` calls `Shortener._encode`, which may not terminate
0 passed, 3 warnings, 0 failures
soma.toml: 1 user-defined properties loaded — NONE applies to this file ([verify] cells = ["TodoService"] names no cell of it)
Temporal: 0 passed, 0 failed
VERIFY OK