Resource objects
ReactorSDK materializes Reactor API responses as typed Ruby resource objects instead of leaving application code to work with anonymous hashes. This page documents the common resource contract, the helper methods attached to specific resource classes, and the wrapper objects used for search and library inspection workflows.
Base resource contract
Every typed resource inherits from ReactorSDK::Resources::BaseResource and exposes a stable API for identifiers, raw attributes, metadata, and serialization.
| Attribute | Data type | Description |
|---|---|---|
| id | String | Adobe resource ID such as |
| type | String | JSON:API resource type such as |
| attributes | Hash | Raw attributes exactly as returned by Adobe. |
| meta | Hash | Response metadata attached to the specific resource. |
| relationships | Hash | Raw JSON:API relationships exactly as returned by Adobe. |
| resource[key] | Object | Fallback raw attribute access by string or symbol key. |
| relationship_data(name) | Hash | Returns the raw relationship object for one relationship name. |
| relationship_id(name) | String | Returns the related resource ID for one-to-one relationships. |
| relationship_ids(name) | Array<String> | Returns related resource IDs for one-to-many relationships. |
| to_h | Hash | Plain hash representation useful for logs and serialization boundaries. |
Equality is based on resource id and type, not on object identity or the exact attribute payload currently loaded.
Typed helpers
Many resource classes add domain-specific helpers so service objects, background jobs, and CLI tooling can express behavior directly instead of repeatedly branching on raw string values.
| Resource | Helper methods |
|---|---|
Property | enabled? |
Host | akamai?, ready? |
Library | buildable?, published? |
LibraryWithResources | buildable?, published?, resource_index, all_resources |
UpstreamChain | nearest_match, found?, each |
Build | succeeded?, pending?, failed? |
Profile | rights |
These helpers are intentionally small, but they matter in production code because they remove repetitive conditional logic from orchestration layers.
Parsed settings
RuleComponent, DataElement, and Extension expose the raw settings field, but they also provide parsed_settings so callers can treat structured configuration consistently.
Settings access
# RC123 = rule component ID.
# DE123 = data element ID.
# EX123 = extension ID.
# Load one rule component so you can inspect its raw and parsed settings.
component = client.rule_components.find("RC123")
# Load one data element for the same reason.
element = client.data_elements.find("DE123")
# Load one extension instance.
extension = client.extensions.find("EX123")
# Raw settings are returned exactly as Adobe stored them.
puts component.settings
# parsed_settings normalizes the value to a Ruby hash when possible.
puts component.parsed_settings.inspect
# Access one parsed setting field directly from the data element hash.
puts element.parsed_settings["source"]
# Inspect the full parsed extension settings hash.
puts extension.parsed_settings.inspect
The behavior is intentionally forgiving:
- If
settingsis already a hash,parsed_settingsreturns it. - If
settingsis a JSON string,parsed_settingsparses it. - If
settingsis blank or malformed,parsed_settingsreturns{}instead of raising.
Special wrappers
Several SDK return types are richer than a standard resource instance because they support specific higher-level workflows.
SearchResults
client.search.perform returns SearchResults, which wraps a heterogeneous collection of typed resources and top-level metadata such as total hit count.
LibraryWithResources
client.libraries.find_with_resources returns a richer library object that includes rules, data elements, and extensions from the JSON:API included array. Each included resource also exposes a gem-added revision_id reader sourced from relationships.latest_revision.data.id, so diffing, audit, and promotion workflows can operate against a single in-memory object graph.
LibraryWithResources example
# LB123 = library ID.
# Load a library together with included rules, data elements, and extensions.
library = client.libraries.find_with_resources("LB123")
# Read the latest revision ID attached to the first included rule.
puts library.rules.first.revision_id
# Print a flat resource_id => revision_id lookup hash.
puts library.resource_index.inspect
# Print all included resource IDs regardless of resource type.
puts library.all_resources.map(&:id).inspect
LibrarySnapshot
client.libraries.find_snapshot returns LibrarySnapshot, which is the SDK's review-oriented library wrapper. It keeps the library comparison context but enriches it with the associated records developers usually need during diff and code-review workflows.
LibrarySnapshot example
# LB_DEV = library ID.
# PR123 = property ID.
# Load the snapshot-aware wrapper for one library.
snapshot = client.libraries.find_snapshot("LB_DEV", property_id: "PR123")
# Rule components are resolved for each rule in the library snapshot.
# When the rule revision includes `rule_components` linkage, the SDK uses that
# point-in-time membership to determine which components belong in the review object.
puts snapshot.rule_components_for_rule("RL123").map(&:id).inspect
# Direct data element dependencies inside the snapshot.
puts snapshot.referenced_data_elements_for("DE123").map(&:name).inspect
# Snapshot-scoped impacted rules, including transitive data element usage.
puts snapshot.impacted_rules_for("DE123").map(&:name).inspect
Comprehensive review wrappers
The additive comprehensive helpers return typed wrappers that keep the original Launch resource under resource, add associated records, and expose diff-ready normalized_payload and normalized_json.
| Attribute | Data type | Description |
|---|---|---|
| ComprehensiveRule | Wrapper | Exposes |
| ComprehensiveDataElement | Wrapper | Exposes |
| ComprehensiveExtension | Wrapper | Exposes |
Comprehensive resource example
# RL123 = rule ID.
# LB_DEV = library ID.
# PR123 = property ID.
rule = client.rules.find_comprehensive(
"RL123",
library_id: "LB_DEV",
property_id: "PR123"
)
# Original Launch rule resource.
puts rule.resource.name
# Associated rule components from the same library snapshot.
puts rule.rule_components.map(&:name).inspect
# Pretty JSON intended for review and diff workflows.
puts rule.normalized_json
UpstreamChain
client.rules.upstream_chain, client.data_elements.upstream_chain, client.extensions.upstream_chain, and client.libraries.upstream_chain_for_resource return UpstreamChain. This wrapper packages the target library context, the target revision, and the ordered upstream entries into one object so applications do not have to hand-roll traversal loops.
UpstreamChain example
# RL123 = rule ID.
# LB_DEV = development library ID.
# PR123 = property ID.
# Resolve the full upstream chain for one rule.
chain = client.rules.upstream_chain(
"RL123",
library_id: "LB_DEV",
property_id: "PR123"
)
# Print the rule revision currently present in the target library.
puts chain.target_revision_id
# nearest_match is the first upstream library where the rule exists.
puts chain.nearest_match&.library&.id
puts chain.nearest_match&.stage
puts chain.nearest_match&.revision_id
# Iterate over every inspected upstream library.
chain.each do |entry|
puts "#{entry.library.id} -> #{entry.present?}"
end
ComprehensiveUpstreamChain
client.rules.comprehensive_upstream_chain, client.data_elements.comprehensive_upstream_chain, client.extensions.comprehensive_upstream_chain, and client.libraries.comprehensive_upstream_chain_for_resource return ComprehensiveUpstreamChain.
| Attribute | Data type | Description |
|---|---|---|
| target_comprehensive_resource | ComprehensiveResource | Snapshot-aware comprehensive wrapper for the resource currently present in the target library. |
| entries | Array<ComprehensiveUpstreamChainEntry> | Ordered upstream entries that carry both raw resource data and comprehensive review objects. |
Upstream comparison data
The upstream comparison model is represented in layers rather than as one composite object.
Chain layer
client.libraries.upstream_libraries(...) returns Array<Library>, ordered nearest upstream first. Those are plain Library resources, so the array gives you traversal order, not embedded comparison state.
Resolved chain layer
client.rules.upstream_chain(...), client.data_elements.upstream_chain(...), client.extensions.upstream_chain(...), and client.libraries.upstream_chain_for_resource(...) return UpstreamChain, which is the SDK's resource-centric upstream wrapper.
| Attribute | Data type | Description |
|---|---|---|
| target_resource | BaseResource | The resource currently present in the target library, if the target library already contains it. |
| target_revision_id | String | The revision ID currently present in the target library for the requested resource. |
| entries | Array<UpstreamChainEntry> | Ordered upstream entries, nearest first, one per inspected upstream library. |
| nearest_match | UpstreamChainEntry | The first upstream entry whose library contains the requested resource. |
| found? | Boolean | Returns |
Comprehensive chain layer
client.rules.comprehensive_upstream_chain(...), client.data_elements.comprehensive_upstream_chain(...), client.extensions.comprehensive_upstream_chain(...), and client.libraries.comprehensive_upstream_chain_for_resource(...) return ComprehensiveUpstreamChain, which adds snapshot-aware associated records and normalized review payloads on top of the lean chain model.
| Attribute | Data type | Description |
|---|---|---|
| target_comprehensive_resource | ComprehensiveResource | Comprehensive wrapper for the resource in the target library. |
| normalized_payload | Hash | Available on each comprehensive entry through |
| normalized_json | String | Pretty JSON intended for code review and diff tooling. |
Resource layer
client.libraries.find_with_resources(...) returns LibraryWithResources, which is the resource-level comparison shape for one library.
| Attribute | Data type | Description |
|---|---|---|
| rules | Array<Rule> | Included rules for the library. Each rule exposes a gem-added |
| data_elements | Array<DataElement> | Included data elements for the library, also exposing |
| extensions | Array<Extension> | Included extensions for the library, also exposing |
| resource_index | Hash | Flattened lookup of |
| all_resources | Array<BaseResource> | Flat array of all included resources regardless of type. |
Snapshot layer
client.libraries.find_snapshot(...) returns LibrarySnapshot, which extends the library-level view with the associated records needed to understand behavioral impact.
| Attribute | Data type | Description |
|---|---|---|
| rule_components_for_rule(rule_or_id) | Array<RuleComponent> | Returns rule components from the same library snapshot, sorted deterministically by |
| referenced_data_elements_for(data_element_or_id) | Array<DataElement> | Returns direct data element dependencies discovered from Launch token syntax and |
| impacted_rules_for(data_element_or_id) | Array<Rule> | Returns snapshot-scoped impacted rules, including transitive data element usage. |
Entry layer
Each UpstreamChainEntry describes one inspected upstream library.
| Attribute | Data type | Description |
|---|---|---|
| library | Library | The upstream library that was inspected for the requested resource. |
| stage | String | Environment stage for the upstream library, such as |
| resource | BaseResource | The matching rule, data element, or extension from that upstream library when present. |
| revision_id | String | Revision ID extracted for that upstream resource from |
| revision | Revision | Full revision wrapper for the upstream resource when a revision lookup was performed. |
| entity_snapshot | Hash | The upstream revision's point-in-time entity snapshot. |
| present? | Boolean | Returns |
Each ComprehensiveUpstreamChainEntry keeps the lean fields above and adds:
comprehensive_resourcenormalized_payloadnormalized_json
Revision layer
When you pick a revision ID from resource_index, client.revisions.find(revision_id) returns a Revision object exposing:
entity_identity_typeentity_snapshotentity_relationships
That final entity_snapshot hash is the point-in-time payload most apps compare once they have resolved the nearest upstream revision.