Skip to content

Wiring & routing — connect nodes, split records

The question for this lesson: so far your pipelines have been a straight line: source, transform, output. But real work branches. Send big orders one way, everything else another. How do you build a pipeline that isn’t a straight line?

  • Read how input: wires one node to another into a graph.
  • Use a route node to split records down named branches.
  • Read the shape of any pipeline by following the wiring.

Every node has a name:. Every non-source node has an input: naming the node it reads from. That’s the whole wiring system: Clinker builds the graph by matching input: values to node name:s.

- type: transform
name: clean # this node is called "clean"
input: customers # it reads from the node named "customers"
🌱 New here? — a DAG

A pipeline is a “DAG”, a directed acyclic graph. “Directed” = data flows one way (input → output). “Acyclic” = no loops; a node can’t eventually feed back into itself. You don’t have to draw it. Just follow each input: to see the shape.

A route node sends each record down one of several named branches, based on a condition. Downstream nodes read a branch with input: <route_name>.<branch>.

- type: route
name: by_size
input: orders
config:
mode: exclusive
conditions:
big: "amount.to_int() > 100" # this branch gets the big orders
default: small # everything else goes here

A record with amount over 100 goes down the big branch; everything else goes down small. Then two outputs read the two branches.

Predict which file each order lands in, then run it.

pipeline.yaml // editable

// quick check

How does the `high` output node get only the big orders?

Change the route so orders over 1000 go to a new vip branch, over 100 stay high, and the rest are low. You’ll add a vip condition and a third output reading by_size.vip.

Create: route by category, not just amount

Section titled “Create: route by category, not just amount”

The Modify split on a number. Now author a route from scratch that splits on a category, a string field. Send each order to a per-region output:

- type: route
name: by_region
input: orders
config:
mode: exclusive
conditions:
us: "region == 'US'" # CXL string equality, not a threshold
eu: "region == 'EU'"
default: other # everything else

Three outputs then read the three branches: by_region.us, by_region.eu, and by_region.other. Over rows A(US), B(EU), C(US), D(APAC):

us.csv: A, C
eu.csv: B
other.csv: D # APAC matched no condition, so it took the default

A route condition is any CXL predicate (> on a number or == on a string), and mode: exclusive sends each record to the first branch it matches, or to default if none. Confirm the branch wiring with clinker run your_pipeline.yaml --explain.