The graph model
A hydrate project is a graph. This page defines its structure, which both the CLI and the v1 API operate on. For the formal, field-by-field reference — the canonical h2o format, its delta grammar, and the invariants the server enforces — see The h2o spec.
A node is a vertex in the graph. There are five kinds:
- Behavior: a unit of work. The default kind.
- Boundary: a node that contains other nodes. Boundaries nest, forming a tree of containment over the graph.
- State: a place shared, mutable data lives. Its input ports are writes and its output ports are reads.
- I/O: the program’s edge with its environment — where data enters or leaves (standard input, arguments, the caller; standard output, an exit code, a response). An I/O node carries exactly one typed port on one side: an output port makes it a source (data flowing into the program), an input port a sink (data flowing out).
- Interface: the program’s edge with the callers that depend on it — a piece of the public API surface, such as a function, type, or parameter that outside code links against. Where I/O is the program’s edge with its environment, interface is its edge with its consumers.
A behavior or boundary may be marked external, representing a system outside the
graph. External nodes carry an external-kind label (for example, rest-api) and
may name a protocol (for example, gRPC).
See Node types in the Quickstart for the shapes and when to reach for each.
Node fields
Section titled “Node fields”Every node has a free-text description. It may also carry:
- Constraints: a list of free-text strings.
- Verifications: a list of free-text strings.
- Aliases: alternate public names the node is also known by.
- Doc URL: an optional documentation link.
Boundary nodes additionally have a user-kind label, a path prefix, and an optional language — the codegen language the boundary declares, which the nodes inside it inherit.
Ports and types
Section titled “Ports and types”A node exposes ports. Every port has a name and a type, written name:type; the
type is always required. There are three channels:
- Inputs: ports a node consumes.
- Outputs: ports a node produces.
- Config: a third channel that is not connected by edges.
A type is a nominal string, such as HotDog, ShortCode, or Rating. Two
ports are compatible when their type strings are equal.
An edge connects an output port to an input port. Config ports cannot be edge endpoints.
The two ports should have the same type, but the type is a hint rather than a
contract: the server accepts an edge whose endpoints disagree. It reports the
mismatch as a type_mismatch coherence finding, which hydrate validate
surfaces.
A type mismatch and an input left unwired are reported rather than enforced:
neither prevents a commit, because a graph under construction is legitimately
incoherent. hydrate validate is the check you run when you want the answer,
and the CLI reference covers what it does
and does not gate.
What the server does refuse is a graph it cannot represent at all: an edge to a port that does not exist, a name that collides with a sibling, a cycle in the containment tree.
Addressing: dotted paths
Section titled “Addressing: dotted paths”Nodes and ports are addressed by dotted path, scoped by the boundaries that contain them.
Api.Rateris the nodeRaterinside the boundaryApi.Api.Rater.scoreis the portscoreon that node.Rateris a top-level node with no enclosing boundary.
A node’s name is unique within its parent scope.
Branches
Section titled “Branches”A project has a main branch and any number of working branches. You create a
working branch with hydrate fork and make edits on it; main is not edited
directly. The graph is stored on the server, and the CLI keeps a local view that
hydrate pull refreshes.
See also
Section titled “See also”- The h2o spec: the formal format reference.
- CLI quickstart: the commands that build a graph.
- CLI command reference: every verb and flag.
- API reference: the same operations over HTTP.
