Skip to content

Upsert a record

Create a new record, or update an existing one when the app provides its rkey.

Trigger: xrpc.procedure:<nsid>. Needs: happyview-db, happyview-record.

local time = require("internal.time")
local tids = require("internal.tids")
local db = require("happyview.db")
local record = require("happyview.record")
function handle(input, ctx)
local rkey = input.rkey or tids.create()
local uri = "at://" .. ctx.caller_did .. "/" .. ctx.collection .. "/" .. rkey
local ts = time.to_iso8601(time.now())
local existing = db.get(uri)
if existing then
local body = existing.record
body.status = input.status
body.updatedAt = ts
return record.put(uri, body)
end
return record.create(ctx.collection, {
status = input.status,
createdAt = ts,
updatedAt = ts,
}, { rkey = rkey })
end
  1. Use the app’s rkey if it sent one, otherwise make a new TID with tids.create(). Leaving rkey out always creates; sending one allows an update.
  2. Build the record’s AT URI from the caller’s DID, the target collection and the rkey, and look it up with db.get.
  3. If the record exists, change its fields and write it back with record.put.
  4. If not, create it with record.create, passing the rkey in the options so the record gets that key. Both writes return { uri, cid }.

internal.time and internal.tids are synchronous in every language. Only library calls, such as db.get and record.put, return promises in JavaScript and TypeScript.

Writing by a known key like this is also how to keep record scripts idempotent. See Create scripts may run more than once.

Terminal window
# Create: no rkey, so a new TID is used
curl -X POST http://127.0.0.1:3000/xrpc/xyz.statusphere.setStatus \
-H "X-Client-Key: $CLIENT_KEY" \
-H "Authorization: DPoP $ACCESS_TOKEN" \
-H "DPoP: $DPOP_PROOF" \
-H "Content-Type: application/json" \
-d '{ "status": "hello" }'
# Update: send the rkey of the existing record
curl -X POST http://127.0.0.1:3000/xrpc/xyz.statusphere.setStatus \
-H "X-Client-Key: $CLIENT_KEY" \
-H "Authorization: DPoP $ACCESS_TOKEN" \
-H "DPoP: $DPOP_PROOF" \
-H "Content-Type: application/json" \
-d '{ "rkey": "3abc123", "status": "updated" }'