soma.cell

Simple REST API

A minimal key-value API with put, get, delete. Serve: soma serve 041_simple_api.cell Test: curl localhost:8080/put/mykey/myvalue curl localhost:8080/get/mykey curl localhost:8080/delete/mykey Run handler directly: soma run 041_simple_api.cell put hello world

Example 041 of the basic Soma programs: a small, commented program that teaches one thing. Every output below was printed by soma 3.2.4 when this page was built.

How it is built

The cell KeyValueAPI declares 4 signals in its face: put(key: String, value: String) -> String, get(key: String) -> String, delete(key: String) -> Map and count() -> Int; keeps 1 memory slot: data (Map<String, String>, persistent and consistent). Handlers: put (line 30), get (line 36), delete (line 46) and count (line 55).

Generated from soma describe on this file.

The source

041_simple_api.cell

// ============================================================================
// 041 — Simple REST API
// ============================================================================
// A minimal key-value API with put, get, delete.
//
// Serve: soma serve 041_simple_api.cell
// Test:  curl localhost:8080/put/mykey/myvalue
//        curl localhost:8080/get/mykey
//        curl localhost:8080/delete/mykey
//
// Run handler directly:
//   soma run 041_simple_api.cell put hello world
//   Expect: world

cell KeyValueAPI {
    face {
        // Each signal becomes an HTTP endpoint when served
        signal put(key: String, value: String) -> String
        signal get(key: String) -> String
        signal delete(key: String) -> Map
        signal count() -> Int
    }

    memory {
        // Persistent storage — survives server restarts
        data: Map<String, String> [persistent, consistent]
    }

    // PUT /put/:key/:value
    on put(key: String, value: String) {
        data.set(key, value)
        return value
    }

    // GET /get/:key
    on get(key: String) {
        let val = data.get(key)
        // Return 404 if key doesn't exist
        if val == () {
            return response(404, map("error", "key not found"))
        }
        return val
    }

    // DELETE /delete/:key
    on delete(key: String) {
        let existed = data.delete(key)
        if existed == false {
            return response(404, map("error", "key not found"))
        }
        return map("deleted", key)
    }

    // GET /count
    on count() {
        return data.len()
    }
}

What the toolchain says

$ soma check 041_simple_api.cell
✓ All checks passed.