- Examples
Update or delete
A single procedure that creates, updates or deletes a record, depending on the uri and delete input fields.
Trigger: xrpc.procedure:<nsid>. Needs: happyview-db, happyview-record.
local db = require("happyview.db")local record = require("happyview.record")
function handle(input, ctx) if input.delete and input.uri then record.delete(input.uri) return { success = true } end
if input.uri then -- Update existing local existing = db.get(input.uri) if not existing then return { error = "RecordNotFound", message = "no record at that uri" } end local body = existing.record body.status = input.status return record.put(input.uri, body) end
if input.delete then return { error = "UriRequired", message = "a delete needs the uri of the record" } end
-- Create new return record.create("xyz.statusphere.record", input)endimport db from "happyview.db";import record from "happyview.record";
export default async function handle(input, ctx) { if (input.delete && input.uri) { await record.delete(input.uri); return { success: true }; }
if (input.uri) { // Update existing const existing = await db.get(input.uri); if (!existing) { return { error: "RecordNotFound", message: "no record at that uri" }; } const body = { ...existing.record, status: input.status }; return record.put(input.uri, body); }
if (input.delete) { return { error: "UriRequired", message: "a delete needs the uri of the record" }; }
// Create new return record.create("xyz.statusphere.record", input);}import db from "happyview.db";import record from "happyview.record";
interface Input { uri?: string; status?: string; delete?: boolean;}
export default async function handle(input: Input) { if (input.delete && input.uri) { await record.delete(input.uri); return { success: true }; }
if (input.uri) { // Update existing const existing = await db.get(input.uri); if (!existing) { return { error: "RecordNotFound", message: "no record at that uri" }; } const body = { ...existing.record, status: input.status }; return record.put(input.uri, body); }
if (input.delete) { return { error: "UriRequired", message: "a delete needs the uri of the record" }; }
// Create new return record.create("xyz.statusphere.record", input);}How it works
Section titled “How it works”- If
input.deleteis truthy andinput.uriis provided, delete the record withrecord.delete, which removes it from the caller’s PDS and the index. - If only
input.uriis provided, load the stored body withdb.get, change its fields, and write it back withrecord.put, which callsputRecord. If no record exists at that URI, return aRecordNotFounderror. - If
input.deleteis set without auri, return aUriRequirederror rather than creating a record. - Otherwise, create a new record from the input with
record.create.
RecordNotFound and UriRequired must be declared under defs.main.errors in the lexicon, as in "errors": [{ "name": "RecordNotFound" }, { "name": "UriRequired" }], for the response to be a 400. An undeclared error is sent as an ordinary 200 response body.
The DPoP proof is signed per request; an app built on the HappyView SDK gets this from its session.
Create:
const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", { method: "POST", headers: { "X-Client-Key": CLIENT_KEY, Authorization: `DPoP ${ACCESS_TOKEN}`, DPoP: DPOP_PROOF, "Content-Type": "application/json", }, body: JSON.stringify({ status: "hello" }),});const data = await response.json();const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", { method: "POST", headers: { "X-Client-Key": CLIENT_KEY, Authorization: `DPoP ${ACCESS_TOKEN}`, DPoP: DPOP_PROOF, "Content-Type": "application/json", }, body: JSON.stringify({ status: "hello" }),});const data = await response.json();let response = client .post("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord") .header("X-Client-Key", client_key) .header("Authorization", format!("DPoP {access_token}")) .header("DPoP", dpop_proof) .json(&serde_json::json!({ "status": "hello" })) .send() .await?;clientKey := "hvc_..." // your API client keyaccessToken := "..." // DPoP access tokendpopProof := "..." // DPoP proof JWT
body := `{ "status": "hello" }`req, err := http.NewRequest("POST", "http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", bytes.NewBufferString(body))if err != nil { log.Fatal(err)}req.Header.Set("X-Client-Key", clientKey)req.Header.Set("Authorization", "DPoP "+accessToken)req.Header.Set("DPoP", dpopProof)req.Header.Set("Content-Type", "application/json")resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)}defer resp.Body.Close()curl -X POST http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord \ -H "X-Client-Key: $CLIENT_KEY" \ -H "Authorization: DPoP $ACCESS_TOKEN" \ -H "DPoP: $DPOP_PROOF" \ -H "Content-Type: application/json" \ -d '{ "status": "hello" }'
Update:
const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", { method: "POST", headers: { "X-Client-Key": CLIENT_KEY, Authorization: `DPoP ${ACCESS_TOKEN}`, DPoP: DPOP_PROOF, "Content-Type": "application/json", }, body: JSON.stringify({ uri: "at://did:plc:abc/xyz.statusphere.record/abc123", status: "updated", }),});const data = await response.json();const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", { method: "POST", headers: { "X-Client-Key": CLIENT_KEY, Authorization: `DPoP ${ACCESS_TOKEN}`, DPoP: DPOP_PROOF, "Content-Type": "application/json", }, body: JSON.stringify({ uri: "at://did:plc:abc/xyz.statusphere.record/abc123", status: "updated", }),});const data = await response.json();let response = client .post("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord") .header("X-Client-Key", client_key) .header("Authorization", format!("DPoP {access_token}")) .header("DPoP", dpop_proof) .json(&serde_json::json!({ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "status": "updated" })) .send() .await?;clientKey := "hvc_..." // your API client keyaccessToken := "..." // DPoP access tokendpopProof := "..." // DPoP proof JWT
body := `{ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "status": "updated" }`req, err := http.NewRequest("POST", "http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", bytes.NewBufferString(body))if err != nil { log.Fatal(err)}req.Header.Set("X-Client-Key", clientKey)req.Header.Set("Authorization", "DPoP "+accessToken)req.Header.Set("DPoP", dpopProof)req.Header.Set("Content-Type", "application/json")resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)}defer resp.Body.Close()curl -X POST http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord \ -H "X-Client-Key: $CLIENT_KEY" \ -H "Authorization: DPoP $ACCESS_TOKEN" \ -H "DPoP: $DPOP_PROOF" \ -H "Content-Type: application/json" \ -d '{ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "status": "updated" }'
Delete:
const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", { method: "POST", headers: { "X-Client-Key": CLIENT_KEY, Authorization: `DPoP ${ACCESS_TOKEN}`, DPoP: DPOP_PROOF, "Content-Type": "application/json", }, body: JSON.stringify({ uri: "at://did:plc:abc/xyz.statusphere.record/abc123", delete: true, }),});const data = await response.json();const response = await fetch("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", { method: "POST", headers: { "X-Client-Key": CLIENT_KEY, Authorization: `DPoP ${ACCESS_TOKEN}`, DPoP: DPOP_PROOF, "Content-Type": "application/json", }, body: JSON.stringify({ uri: "at://did:plc:abc/xyz.statusphere.record/abc123", delete: true, }),});const data = await response.json();let response = client .post("http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord") .header("X-Client-Key", client_key) .header("Authorization", format!("DPoP {access_token}")) .header("DPoP", dpop_proof) .json(&serde_json::json!({ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "delete": true })) .send() .await?;clientKey := "hvc_..." // your API client keyaccessToken := "..." // DPoP access tokendpopProof := "..." // DPoP proof JWT
body := `{ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "delete": true }`req, err := http.NewRequest("POST", "http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord", bytes.NewBufferString(body))if err != nil { log.Fatal(err)}req.Header.Set("X-Client-Key", clientKey)req.Header.Set("Authorization", "DPoP "+accessToken)req.Header.Set("DPoP", dpopProof)req.Header.Set("Content-Type", "application/json")resp, err := http.DefaultClient.Do(req)if err != nil { log.Fatal(err)}defer resp.Body.Close()curl -X POST http://127.0.0.1:3000/xrpc/xyz.statusphere.setRecord \ -H "X-Client-Key: $CLIENT_KEY" \ -H "Authorization: DPoP $ACCESS_TOKEN" \ -H "DPoP: $DPOP_PROOF" \ -H "Content-Type: application/json" \ -d '{ "uri": "at://did:plc:abc/xyz.statusphere.record/abc123", "delete": true }'
© HappyProto

