The Node class provides comprehensive tree management functionality, enabling navigation, querying, and manipulation of construct trees. Every construct has an associated Node that manages its relationships and metadata.
Core class that manages construct tree relationships, paths, addressing, and child management.
/**
* Represents the construct node in the scope tree.
*/
class Node {
/**
* Separator used to delimit construct path components.
*/
static readonly PATH_SEP: string; // "/"
/**
* Returns the node associated with a construct.
* @param construct the construct
* @deprecated use `construct.node` instead
*/
static of(construct: IConstruct): Node;
/**
* Returns the scope in which this construct is defined.
* The value is `undefined` at the root of the construct scope tree.
*/
readonly scope?: IConstruct;
/**
* The id of this construct within the current scope.
* This is a scope-unique id. To obtain an app-unique id for this construct, use `addr`.
*/
readonly id: string;
/**
* The full, absolute path of this construct in the tree.
* Components are separated by '/'.
*/
readonly path: string;
/**
* Returns an opaque tree-unique address for this construct.
* Addresses are 42 characters hexadecimal strings. They begin with "c8"
* followed by 40 lowercase hexadecimal characters (0-9a-f).
*/
readonly addr: string;
/**
* All direct children of this construct.
*/
readonly children: IConstruct[];
/**
* All parent scopes of this construct.
* The last element in the list will always be the current construct
* and the first element will be the root of the tree.
*/
readonly scopes: IConstruct[];
/**
* Returns the root of the construct tree.
*/
readonly root: IConstruct;
/**
* Returns true if this construct or the scopes in which it is defined are locked.
*/
readonly locked: boolean;
/**
* Returns the child construct that has the id `Default` or `Resource`.
* This is usually the construct that provides the bulk of the underlying functionality.
*/
readonly defaultChild?: IConstruct;
/**
* Override the defaultChild property.
* This should only be used in the cases where the correct default child
* is not named 'Resource' or 'Default' as it should be.
*/
defaultChild?: IConstruct;
}Methods for finding, accessing, and managing child constructs in the tree.
/**
* Return a direct child by id
* @param id Identifier of direct child
* @returns Child with the given id.
* @throws Error if the child is not found
*/
findChild(id: string): IConstruct;
/**
* Return a direct child by id, or undefined
* @param id Identifier of direct child
* @returns the child if found, or undefined
*/
tryFindChild(id: string): IConstruct | undefined;
/**
* Return this construct and all of its children in the given order
* @param order Traversal order (default: PREORDER)
* @returns Array of all constructs in the subtree
*/
findAll(order?: ConstructOrder): IConstruct[];
/**
* Remove the child with the given name, if present.
* @param childName Name of child to remove
* @returns Whether a child with the given name was deleted.
*/
tryRemoveChild(childName: string): boolean;Usage Examples:
import { Construct, RootConstruct, ConstructOrder } from "constructs";
const app = new RootConstruct("App");
const api = new Construct(app, "API");
const database = new Construct(api, "Database");
const cache = new Construct(api, "Cache");
// Find direct children
const foundDb = api.node.findChild("Database");
console.log(foundDb === database); // true
const maybeCache = api.node.tryFindChild("Cache");
console.log(maybeCache === cache); // true
const notFound = api.node.tryFindChild("NonExistent");
console.log(notFound); // undefined
// Get all constructs in tree
const allPreorder = app.node.findAll(ConstructOrder.PREORDER);
console.log(allPreorder); // [app, api, database, cache]
const allPostorder = app.node.findAll(ConstructOrder.POSTORDER);
console.log(allPostorder); // [database, cache, api, app]
// Remove children
const removed = api.node.tryRemoveChild("Cache");
console.log(removed); // true
console.log(api.node.children.length); // 1Properties and methods for navigating the construct tree hierarchy.
/**
* All direct children of this construct.
*/
readonly children: IConstruct[];
/**
* All parent scopes of this construct.
* The last element in the list will always be the current construct
* and the first element will be the root of the tree.
*/
readonly scopes: IConstruct[];
/**
* Returns the root of the construct tree.
*/
readonly root: IConstruct;
/**
* The full, absolute path of this construct in the tree.
* Components are separated by '/'.
*/
readonly path: string;
/**
* Returns an opaque tree-unique address for this construct.
* Addresses are 42 characters hexadecimal strings.
*/
readonly addr: string;Usage Examples:
import { Construct, RootConstruct } from "constructs";
const app = new RootConstruct("MyApp");
const vpc = new Construct(app, "VPC");
const subnet = new Construct(vpc, "Subnet");
const instance = new Construct(subnet, "Instance");
// Navigate hierarchy
console.log(instance.node.path); // "VPC/Subnet/Instance"
console.log(subnet.node.children); // [instance]
console.log(instance.node.scopes); // [app, vpc, subnet, instance]
console.log(instance.node.root === app); // true
// Unique addressing
console.log(instance.node.addr); // e.g., "c8a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0"
console.log(vpc.node.addr !== subnet.node.addr); // true
// Direct children access
vpc.node.children.forEach(child => {
console.log(`Child: ${child.node.id}`); // "Child: Subnet"
});Mechanism to prevent modification of construct trees, typically used during synthesis phases.
/**
* Locks this construct from allowing more children to be added.
* After this call, no more children can be added to this construct or to any children.
*/
lock(): void;
/**
* Returns true if this construct or the scopes in which it is defined are locked.
*/
readonly locked: boolean;Usage Examples:
import { Construct, RootConstruct } from "constructs";
const app = new RootConstruct("App");
const service = new Construct(app, "Service");
// Lock the tree
app.node.lock();
console.log(app.node.locked); // true
console.log(service.node.locked); // true (inherited)
// Attempting to add children after locking throws an error
try {
new Construct(app, "NewService"); // Throws: Cannot add children during synthesis
} catch (error) {
console.log(error.message);
}
try {
new Construct(service, "Component"); // Throws: Cannot add children to "Service" during synthesis
} catch (error) {
console.log(error.message);
}System for identifying the primary child construct that provides core functionality.
/**
* Returns the child construct that has the id `Default` or `Resource`.
* This is usually the construct that provides the bulk of the underlying functionality.
* @throws if there is more than one child with these names
* @returns a construct or undefined if there is no default child
*/
readonly defaultChild?: IConstruct;
/**
* Override the defaultChild property.
* This should only be used in the cases where the correct default child
* is not named 'Resource' or 'Default' as it should be.
*/
defaultChild?: IConstruct;Usage Examples:
import { Construct, RootConstruct } from "constructs";
const app = new RootConstruct("App");
const service = new Construct(app, "Service");
// Create default child automatically recognized
const resource = new Construct(service, "Resource");
console.log(service.node.defaultChild === resource); // true
// Create another default child pattern
const defaultChild = new Construct(service, "Default");
// Would throw error: Cannot determine default child for Service.
// There is both a child with id "Resource" and id "Default"
// Manually override default child
const customChild = new Construct(service, "CustomMain");
service.node.defaultChild = customChild;
console.log(service.node.defaultChild === customChild); // true
// Reset to automatic detection
service.node.defaultChild = undefined;
console.log(service.node.defaultChild === resource); // trueEnumeration options for controlling tree traversal order.
/**
* In what order to return constructs
*/
enum ConstructOrder {
/**
* Depth-first, pre-order
*/
PREORDER = 0,
/**
* Depth-first, post-order (leaf nodes first)
*/
POSTORDER = 1
}Usage Examples:
import { Construct, RootConstruct, ConstructOrder } from "constructs";
const app = new RootConstruct("App");
const frontend = new Construct(app, "Frontend");
const backend = new Construct(app, "Backend");
const database = new Construct(backend, "Database");
// Pre-order traversal (parents before children)
const preorder = app.node.findAll(ConstructOrder.PREORDER);
console.log(preorder.map(c => c.node.path || "<root>"));
// ["<root>", "Frontend", "Backend", "Backend/Database"]
// Post-order traversal (children before parents)
const postorder = app.node.findAll(ConstructOrder.POSTORDER);
console.log(postorder.map(c => c.node.path || "<root>"));
// ["Frontend", "Backend/Database", "Backend", "<root>"]