Skip to main content

Overview

The Hydrator trait defines how candidates are enriched with additional data. Hydrators run in parallel and populate specific fields on candidate objects by making async calls to external services.
Hydrators MUST maintain the same candidate order and count. They cannot drop or reorder candidates - use Filter stages for removal.

Trait Definition

Type Parameters

generic
The query type that contains request context and parametersConstraints: Clone + Send + Sync + 'static
generic
The candidate type that will be hydrated with additional fieldsConstraints: Clone + Send + Sync + 'static

Methods

enable

fn
Determines whether this hydrator should run for the given query
&Q
Reference to the query object
bool
Returns true if this hydrator should run, false to skip. Default implementation returns true.

hydrate

async fn
Performs async operations to fetch data and returns candidates with hydrated fields
&Q
Reference to the query object
&[C]
Slice of candidates to hydrate
Result<Vec<C>, String>
Returns a vector with the same length and order as input, with only this hydrator’s fields populated. Returns an error message on failure.
The returned vector MUST have the same candidates in the same order as the input. Dropping or reordering candidates is not allowed.

update

fn
Copies hydrated fields from a hydrated candidate into the target candidate
&mut C
Mutable reference to the candidate to update
C
The hydrated candidate containing new field values
Only copy the fields that this hydrator is responsible for. Leave other fields unchanged.

update_all

fn
Updates all candidates with their corresponding hydrated fields
&mut [C]
Mutable slice of candidates to update
Vec<C>
Vector of hydrated candidates from the hydrate method
The default implementation iterates and calls update for each pair. Override for custom batching logic.

name

fn
Returns a stable name for logging and metrics
&'static str
A short type name derived from the implementing struct

Example Implementation

Here’s a real example that hydrates tweet author information from the Gizmoduck user service:

Usage Notes

  • Multiple hydrators run in parallel to minimize latency
  • Batch operations in hydrate for efficiency (e.g., fetch all users in one request)
  • Only populate fields relevant to this hydrator in the returned candidates
  • Use Default::default() for other fields to avoid accidentally overwriting data
  • The pipeline merges results by calling update for each hydrator
  • Consider implementing custom update_all for optimized batch updates

Best Practices

  1. Maintain Order: Always return candidates in the same order as received
  2. Batch Requests: Deduplicate IDs and make bulk requests to external services
  3. Partial Hydration: Handle missing data gracefully with Option types
  4. Error Handling: Provide descriptive error messages for debugging
  5. Field Isolation: Only update fields owned by this hydrator in the update method
The QueryHydrator trait is used for hydrating the query/request object itself before candidate retrieval, rather than hydrating candidates.

Key Differences from Hydrator

  • QueryHydrator: Enriches the request/query with user context (e.g., user action sequences, feature flags)
  • Hydrator: Enriches candidates with additional metadata (e.g., author profiles, media info)
  • QueryHydrator: Runs early in the pipeline, before candidate sourcing
  • Hydrator: Runs after candidates are retrieved from sources
  • QueryHydrator: Only generic over query type Q
  • Hydrator: Generic over both query Q and candidate C types

Example: UserActionSeqQueryHydrator

home-mixer/query_hydrators/user_action_seq_query_hydrator.rs
Query hydrators are essential for Phoenix models, which require user engagement history to make accurate predictions.

See Also