ApexEloquent

A data-access OSS for Apex that separates query construction from query execution. The domain draws the blueprint of a query with Scribe; IEloquent takes care of running it.

Why ApexEloquent

Separating Query Construction From ExecutionQuery Delegation Pattern

The widely adopted Selector Pattern in Salesforce development has clear strengths: queries can be shared, and business logic fetches data via methods rather than embedding queries. But over long-term operation, every time someone wants "a slightly different query", a method or variable patch piles on, and that initial simplicity slowly erodes. On top of that, tests themselves require a database — you're stuck writing only integration tests.

ApexEloquent redesigns the Repository pattern for Apex, adopting the Query Delegation Pattern in which query "construction" and "execution" are kept separate. The domain layer draws the blueprint of a query with Scribe, hands it to IEloquent.get(scribe), and in production Eloquent issues the SOQL.

In tests, you just swap IEloquent for MockEloquent via DI, and you can write unit tests that don't go through the database. A framework that doesn't get in the way of long-term development.

Domain
Scribe
Query blueprint
Delegation
IEloquent
Production / Mock via DI
Execution
Eloquent / MockEloquent
Real SOQL / DB-less

Core Building Blocks

Three Core Pieces

Query Builder

Scribe

An immutable, typed method-chain query builder. SELECT / WHERE / sorting / aggregation / GROUP BY / HAVING all assemble through one API. Each method returns a new Scribe, so deriving a count query and a list query from the same conditions is natural.

Usage guide →
Data Access

IEloquent (Eloquent / MockEloquent)

The interface that receives a Scribe and executes SOQL. DML (insert / update / upsert / delete) is handled uniformly with bulk overloads. Production uses Eloquent, tests use MockEloquent, swapped via the Layered Constructor Pattern.

Usage guide →
Record Wrapper

IEntry (Entry / MockEntry)

A unified wrapper that lets you read SObject and AggregateResult through the same get(field). MockEntry can also set non-writable fields freely — formula fields, rollups, parent relationships, auto-number.

Usage guide →

Why This Design

ApexEloquent's Distinctive Design

Mock Non-Writable Fields, Parent-Child, and AggregateResult

Fields you can't normally write to — formula fields, rollups, parent relationships, auto-number — are set freely in mocks. Parent-child hierarchies and the result of aggregate queries are mocked through the same IEntry interface, consistently.

Read the MockEntry Deep Dive →

ORM and Mocking, Together

Many ORM libraries stop at query construction and leave DB-less testing to another library or a handwritten mock. ApexEloquent takes you from query construction all the way to fast, DB-less unit tests written against the built-in mocks — nonstop.

Read the MockEntry Deep Dive →

Catch SELECT Omissions at Test Time

A real SObject fetched via SOQL throws immediately when you access a field that wasn't in the SELECT clause. But the common test pattern of injecting SObjects lets access to unfetched fields pass silently — unnoticed in unit tests, surfacing only in integration tests or in production. ApexEloquent remembers the SELECT clause of Scribe and, even with mocked injection, throws at unit-test time when an unfetched field is accessed.

Read the SELECT-Omission Safety Net Deep Dive →

Spy + failOn for Retry-Style Tests

Spy properties let you verify that records were created / updated / deleted correctly — all DB-less. The failOn methods let you raise errors at exactly the timing you intend, so you can verify catch blocks without polluting production code.

Read Data Access, DML, IEntry, Mock →

Deep Dives

Digging into Motivations and Distinctive Features

Why ApexEloquent ended up in this shape, and how its distinctive features earn their keep — five documents go deep.

Where It Sits in Apex Stem

Position in Apex Stem

ApexEloquent is the Data Access piece among the four OSS that make up Apex Stem. It comes into play in the Usecase layer of the Handler-Usecase Architecture whenever DB access is involved, and it carries the "Usecase unit test ↔ ApexEloquent" half of the test strategy.

ApexEloquent
Data Access: SOQL / DML + Mock
ApexBlueprint
Test Data Factory: real-DML data for integration tests
ApexTrace
Lifecycle Logging: Usecase path tracing and test verification
ApexTools
Foundation: TriggerHandler base + HTTP DI wrapper
Related Documents

Start with the Developer Guide

The developer guide walks through three usage paths — building queries with Scribe, fetching data and running DML, and working with relations — using real code. The API references can be cross-checked alongside.