workflow.Node interface:
Type()returns the node’s kind (aNodeTypestring). Embeddingworkflow.BaseNodesupplies this for you.Validate()runs at compile time. Return an error to reject a misconfigured node before the workflow ever runs.Execute()runs at run time. It returns a partial state update, the output port to follow, and an error.
A basic node
EmbedBaseNode to get Type(), then implement Validate and Execute:
Capture host dependencies (DB handles, HTTP clients, API clients) on the node struct via its constructor. The
workflow.NodeFactory type — func() (Node, error) — is provided for hosts that build nodes lazily.Reading run state
All nodes share a singleInput. Its RunContext is an opaque map[string]any that accumulates as the run progresses. Read from it in two ways:
workflow.ResolvePath(in, "a.b.c")— walk a dotted path into nested maps. Returns(value, ok).in.RunContext["key"]— direct access to a top-level key.
Writing run state
The map you return fromExecute is deep-merged into RunContext: keys that hold maps on both sides merge recursively, and all other values replace (last writer wins at the leaves). You only return what changed — never the whole context.
Output ports
The second return value ofExecute is the port — the named output the engine follows to pick the next node. Return workflow.DefaultPort ("default") for linear flow, or a custom port name to branch:
AddEdgeOnPort. A port with no matching edge simply ends that branch.
Typed inputs and outputs
Working withmap[string]any everywhere is error-prone. The package provides generic helpers to round-trip between the wire format and your own structs via JSON:
DecodeInput[T](map[string]any) (*T, error)— unmarshal the run context (or any map) into a typed struct.EncodeOutput[T](*T) (map[string]any, error)— marshal a typed result back into themap[string]anyevery node returns.
Pausing instead of completing
A node can suspend the entire run instead of returning output — for example, to wait on a human approval. Returnworkflow.Pause(payload) from Execute; the run stops cleanly with its state preserved. See Pausing & Resuming for the full flow.