soma.cell

Key-value store API with namespaced keys and a bulk export endpoint

PUT /kv/<key> sets, GET reads, DELETE removes, GET /kv exports all.

A Soma program from the web part of the verified corpus: 65 lines, cells KvStore, KvStoreTest. It passes soma check with soma 3.2.4.

How it is built

The cell KvStore declares 5 signals in its face: request(method: String, path: String, body: String) -> Map, put(key: String, value: String) -> Map, get_one(key: String) -> Map, del(key: String) -> Map and export() -> Map; keeps 1 memory slot: kv (Map<String, String>, persistent and consistent). Handlers: put (line 18), get_one (line 23), del (line 29), export (line 35) and request (line 43).

The file also holds 1 test cell (KvStoreTest) with 6 assertions, run by soma test.

Generated from soma describe on this file.

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"]

kv_store.cell

// Key-value store API with namespaced keys and a bulk export endpoint.
// PUT /kv/<key> sets, GET reads, DELETE removes, GET /kv exports all.

cell KvStore {
    face {
        signal request(method: String, path: String, body: String) -> Map
        signal put(key: String, value: String) -> Map
        signal get_one(key: String) -> Map
        signal del(key: String) -> Map
        signal export() -> Map
        promise all_persistent
    }

    memory {
        kv: Map<String, String> [persistent, consistent]
    }

    on put(key: String, value: String) {
        kv.set(key, value)
        return map("key", key, "value", value)
    }

    on get_one(key: String) {
        let v = kv.get(key)
        if v == () { return response(404, map("error", "no such key")) }
        return map("key", key, "value", v)
    }

    on del(key: String) {
        let existed = kv.delete(key)
        if existed == false { return response(404, map("error", "no such key")) }
        return map("deleted", key)
    }

    on export() {
        let out = map()
        for k in kv.keys {
            out = with(out, k, kv.get(k))
        }
        return out
    }

    on request(method: String, path: String, body: String) {
        let req = map("method", method, "path", path)
        match req {
            {method: "GET",    path: "/kv"}        -> export()
            {method: "PUT",    path: "/kv/" + key} -> put(key, from_json(body).value)
            {method: "GET",    path: "/kv/" + key} -> get_one(key)
            {method: "DELETE", path: "/kv/" + key} -> del(key)
            _                                      -> response(404, map("error", "no route"))
        }
    }
}

cell test KvStoreTest {
    rules {
        assert put("a", "1").value == "1"
        assert put("b", "2").value == "2"
        assert get_one("a").value == "1"
        assert export().b == "2"
        assert del("a").deleted == "a"
        assert get_one("a")._status == 404
    }
}

What the toolchain says

Run on a fresh copy of the program at build time; the outputs are pasted unedited.

$ soma check kv_store.cell
✓ All checks passed.
$ soma test kv_store.cell
test KvStoreTest ...
  ✓ assert put("a", "1").value == "1"
  ✓ assert put("b", "2").value == "2"
  ✓ assert get_one("a").value == "1"
  ✓ assert export().b == "2"
  ✓ assert del("a").deleted == "a"
  ✓ assert get_one("a")._status == 404

6 tests: 6 passed, 0 failed
$ soma verify kv_store.cell
Verifying kv_store.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

from_json, map, response, with

Source file: /corpus/web/kv_store.cell · examples/corpus/web/kv_store.cell