Mini blog API with tag filtering. Posts carry a list of tags;
GET /posts?tag=X filters in-memory using a pipe over stored records.
A Soma program from the web part of the verified corpus: 61 lines, cells Blog, BlogTest. It passes soma check with soma 3.2.4.
How it is built
The cell Blog declares 4 signals in its face: request(method: String, path: String, body: String) -> Map, create_post(data: Map) -> Map, list_all() -> List and by_tag(tag: String) -> List; keeps 1 memory slot: posts (Map<String, Map>, persistent and consistent). Handlers: create_post (line 17), list_all (line 25), by_tag (line 27) and request (line 45). Private helpers: _demo.
The file also holds 1 test cell (BlogTest) with 1 assertion, 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"]blog_tags.cell
// Mini blog API with tag filtering. Posts carry a list of tags;
// GET /posts?tag=X filters in-memory using a pipe over stored records.
cell Blog {
face {
signal request(method: String, path: String, body: String) -> Map
signal create_post(data: Map) -> Map
signal list_all() -> List
signal by_tag(tag: String) -> List
promise all_persistent
}
memory {
posts: Map<String, Map> [persistent, consistent]
}
on create_post(data: Map) {
let id = to_string(next_id())
let tagstr = data.tags |> join(",")
let post = map("id", id, "title", data.title, "body", data.body, "tags", tagstr)
posts.set(id, post)
return post
}
on list_all() { return posts.values }
on by_tag(tag: String) {
let needle = concat(",", concat(tag, ","))
return posts.values |> filter(p => contains(concat(",", concat(p.tags, ",")), needle))
}
on _demo() {
create_post(map("title", "Hi", "body", "first", "tags", list("soma", "intro")))
create_post(map("title", "Two", "body", "second", "tags", list("soma")))
create_post(map("title", "Three", "body", "third", "tags", list("rust")))
// fingerprint: total/soma-count/rust-count/first-soma-title
let parts = list(
to_string(len(list_all())),
to_string(len(by_tag("soma"))),
to_string(len(by_tag("rust"))),
to_string(len(by_tag("missing"))))
return parts |> join("/")
}
on request(method: String, path: String, body: String) {
let req = map("method", method, "path", path)
match req {
{method: "GET", path: "/posts"} -> list_all()
{method: "POST", path: "/posts"} -> create_post(from_json(body))
{method: "GET", path: "/posts/tag/" + t} -> by_tag(t)
_ -> response(404, map("error", "no route"))
}
}
}
cell test BlogTest {
rules {
assert _demo() == "3/2/1/0"
}
}What the toolchain says
$ soma check blog_tags.cell
✓ All checks passed.$ soma test blog_tags.cell
test BlogTest ...
✓ assert _demo() == "3/2/1/0"
1 tests: 1 passed, 0 failed$ soma verify blog_tags.cell
Verifying blog_tags.cell...
No state machine in this program: nothing to prove beyond `soma check` (invariants and lifecycles are what verify proves).
note: the soma.toml beside this file declares [verify] properties; none applies here (no state machine)
VERIFY OK (vacuous — no state machine)Builtins used
concat, contains, filter, from_json, join, len, list, map, next_id, response, to_string