Skip to content

Sidecar records

Create two records with different collection NSIDs but the same rkey, linking them together by key.

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

local time = require("internal.time")
local tids = require("internal.tids")
local record = require("happyview.record")
function handle(input, ctx)
local rkey = tids.create()
local ts = time.to_iso8601(time.now())
local post = record.create("xyz.statusphere.post", {
text = input.text,
createdAt = ts,
}, { rkey = rkey })
local metadata = record.create("xyz.statusphere.postMetadata", {
lang = input.lang or "en",
source = input.source or "web",
createdAt = ts,
}, { rkey = rkey })
return { post = post, metadata = metadata }
end
  1. Mint a single TID with tids.create() to use as the rkey for both records.
  2. Create a record in each collection with record.create, passing the shared rkey in opts.
  3. Return both { uri, cid } results so the app knows the identity of each record.

The DPoP proof is signed per request; an app built on the HappyView SDK gets this from its session.

const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.createPost", {
method: "POST",
headers: {
"X-Client-Key": CLIENT_KEY,
Authorization: `DPoP ${ACCESS_TOKEN}`,
DPoP: DPOP_PROOF,
"Content-Type": "application/json",
},
body: JSON.stringify({
text: "Hello world",
lang: "en",
source: "web",
}),
});
const data = await response.json();

The response includes URIs for both the post and its metadata:

{
"post": {
"uri": "at://did:plc:abc/xyz.statusphere.post/3abc123",
"cid": "bafyrei..."
},
"metadata": {
"uri": "at://did:plc:abc/xyz.statusphere.postMetadata/3abc123",
"cid": "bafyrei..."
}
}

Use sidecar records to keep a primary record small and store related data, such as metadata, reactions or settings, in another collection under the same rkey. Because they share an rkey, you can derive one URI from the other:

at:// did:plc:abc /xyz.statusphere.post /3abc123
at:// did:plc:abc /xyz.statusphere.postMetadata /3abc123
^^^^^^^ same rkey