Workflow API
WorkflowHandle manages realm workflows. Workflows are server-side resources
exposed at /admin/realms/{realm}/workflows; this handle forwards server-side
search and pagination parameters instead of loading every workflow into
memory.
Access
const workflow = realm.workflow('approval');
Core Methods
get()— exact-name lookup via server-sidesearch+exact:true. Returns the single match,nullif none, and throwsDuplicateWorkflowNameErrorif more than one workflow shares the exact name.getById(id)— direct lookup by internal workflow id via/admin/realms/{realm}/workflows/{id}. Returnsnullif the id does not exist.create(data)/update(data)/delete()/discard()/ensure(data)list({ page?, pageSize?, first?, max? })— a single server-side page (first/max). Does not slice the result; returns the page the server produced.listAll({ pageSize?, first?, maxPages?, signal? })— iterates the full collection viafetchAll, advancing by the page length Keycloak returned. ValidatespageSize/first/maxPages, bounds the loop withRangeError, and supports anAbortSignal.listAllStream({ pageSize?, first?, maxPages?, signal? })— async iterator yielding one workflow page at a time, with the same bounded-loop guarantees aslistAllplus reference-identity repeated-page protection.
Errors
WorkflowNotFoundError— raised byupdate/delete/discard(viarequireWorkflow) when the named workflow cannot be resolved in the realm. CarriesrealmNameandworkflowNameso callers can distinguish it from a transient HTTP error without string-matching the message.DuplicateWorkflowNameError— raised byget(and the staticgetByName) when more than one workflow matches the exact name. The previous silent "first match wins" behavior could let a duplicate collision masquerade as a successful single-workflow provision; this handle now fails loudly soensure()/create()callers can react. Callers that intentionally want all matches should uselist/listAll/listAllStream.
Example
const workflow = await realm.workflow('approval').ensure({
enabled: true,
});
await workflow.update({
enabled: false,
});
// Request only the second page (server-side pagination):
const pageTwo = await realm.workflow('approval').list({ page: 2, pageSize: 10 });
// Iterate every workflow in the realm without buffering everything:
for await (const page of realm.workflow('approval').listAllStream({ pageSize: 100 })) {
for (const w of page) {
console.log(w.id, w.name);
}
}
// Or collect the full collection (validated, bounded, cancellable):
const all = await realm
.workflow('approval')
.listAll({ pageSize: 100, maxPages: 50, signal: controller.signal });
Important Behavior
WorkflowHandle now follows the same lifecycle contract as the other mutable
resource handles in this library.
update(...)updates an existing workflow.ensure(...)creates the workflow if it does not exist, or updates it if it already exists.- The update path preserves unspecified fields by merging your partial input into the current workflow representation before sending the admin update call.
get()/getById()cache the resolved representation on the handle; a second call returns the cache without re-fetching. Use a fresh handle instance to force a re-read.