How the client works

You do not need to understand every internal layer before you use ReactorSDK, but it helps to know what the client is already doing for you. This page explains the moving parts behind a normal ReactorSDK::Client so debugging and day-to-day use feel less mysterious.

Client composition

When you initialize the client, the SDK validates configuration and then builds infrastructure in a fixed order.

AttributeDescription
Configuration

Stores constructor options and validates required credentials immediately.

Authentication

Fetches and refreshes Adobe IMS access tokens using OAuth server-to-server.

RateLimiter

Enforces a per-client token bucket so requests stay within Adobe's documented request budget.

Connection

Wraps Faraday, injects headers, performs retries, and raises typed SDK errors.

Paginator

Follows cursor-based pagination and always returns complete collections.

ResponseParser

Converts JSON:API response hashes into typed Ruby resource objects.

All endpoint groups, such as properties, rules, libraries, and revisions, are then instantiated with those shared dependencies.

Connection behavior

The Connection object centralizes outbound Reactor API behavior so endpoint classes can stay focused on paths, payloads, and return types.

Responsibilities

  • Inject Authorization, x-api-key, x-gw-ims-org-id, and Accept headers.
  • Apply the shared rate limiter before every request.
  • Retry transient failure statuses with backoff and jitter.
  • Normalize 204 No Content responses to nil.
  • Parse JSON responses and raise typed errors for non-success statuses.

Important defaults

SettingValue
Base URLhttps://reactor.adobe.io
Accept headerapplication/vnd.api+json;revision=1
Content typeapplication/vnd.api+json
Timeout30 seconds
Open timeout10 seconds
Retry statuses429, 500, 502, 503, 504

Pagination by default

Cursor pagination is one of the most important implementation details in ReactorSDK. Adobe list endpoints can silently truncate your result set if you request only the first page. The SDK avoids that by always routing list calls through the paginator.

List methods are fully paginated

# PR123 = property ID.
# LB123 = library ID.
# Each call automatically walks all pages until Adobe stops returning links.next.
rules     = client.rules.list_for_property("PR123")
libraries = client.libraries.list_for_property("PR123")
builds    = client.builds.list_for_library("LB123")

Rate limiting and retries

The SDK models Adobe's documented limit of 120 requests per minute per access token with a token bucket limiter. One limiter is created per ReactorSDK::Client, which means multiple client instances do not share rate limit state.

  • The bucket starts full, so the first burst of requests can proceed immediately.
  • When tokens run low, callers block until enough time has elapsed for the next token.
  • Separate client instances keep credentials, rate-limit state, and token caches isolated.

Retries are handled at the Faraday layer. Application code usually only needs business-level retry logic, such as retrying a background job later or polling for a build result.

Parsing and typed endpoints

The endpoint layer is intentionally thin because most shared behavior is centralized. Endpoint classes inherit payload helpers from BaseEndpoint, then call shared helpers such as fetch_resource, list_resources, create_resource, and update_resource.

That is why the public API reads consistently:

Predictable endpoint style

# Fetch one property by Adobe property ID.
client.properties.find("PR123")
# List all rules that belong to a property.
client.rules.list_for_property("PR123")
# Create a new library inside a property.
client.libraries.create(property_id: "PR123", name: "Release 1.0")
# Upload a zipped extension package from disk.
client.extension_packages.create(package_path: "tmp/my_extension.zip")

The parser uses a type registry for heterogeneous results like search responses, and it has special handling for revision lookups where the full entity snapshot appears in the JSON:API included array.

Was this page helpful?