Skip to content

CrudIncludePreloader

Viames Marino edited this page Apr 22, 2026 · 1 revision

Pair framework: CrudIncludePreloader

Pair\Api\CrudIncludePreloader lets a CRUD resource bulk-load relationship includes before CrudController transforms each record.

Use it when GET /api/{resource}?include=... would otherwise run one relation query per parent record.

Contract

namespace Pair\Api;

use Pair\Orm\ActiveRecord;

interface CrudIncludePreloader {
	public function preload(array $objects, array $includes, CrudResourceConfig $config): array;
}

The returned array must be grouped by include name, then by parent key:

[
	'group' => [
		7 => $groupRecord,
		8 => $anotherGroupRecord,
	],
]

Parent keys may be:

  • the parent record primary key
  • the original collection key
  • spl_object_id($parent)

Relation values may be null, an ActiveRecord, or a Pair\Orm\Collection. CrudController still applies includeReadModels, includeResources, or the related model's own CRUD config before writing the response payload.

Configuration

$this->crud('users', \App\Orm\User::class, [
	'readModel' => \App\Api\ReadModels\UserReadModel::class,
	'includes' => ['group'],
	'includeReadModels' => [
		'group' => \App\Api\ReadModels\GroupReadModel::class,
	],
	'includePreloader' => \App\Api\Preloaders\UserIncludePreloader::class,
]);

includePreloader is optional. If it is not configured, CrudController keeps the legacy per-record include loading behavior. When configured, the class must exist and implement Pair\Api\CrudIncludePreloader; invalid classes fail explicitly with a LogicException.

Notes

  • The preloader runs once per collection response, not once per record.
  • Return only includes requested in the current response.
  • Do not change response shapes in the preloader; it should load relation objects, not serialize them.
  • Return Pair\Orm\Collection values for many-record relations so Pair can keep the same include transformation path.
  • Keep authorization and tenant filters in the bulk query, exactly as you would in per-record relation methods.

See also: CrudController, CrudResourceConfig, ApiExposable.

Clone this wiki locally