A sync provider is a class that implements SyncProviderInterface
to propagate data to and from a backend, e.g. an API or database.
For a provider to perform sync operations on an entity of a given type, it must also implement the entity's provider interface, which--aside from entities with a registered namespace helper--has the following name:
<entity_namespace>\Provider\<entity>Provider
A provider servicing Acme\Sync\User
entities would need to implement the
Acme\Sync\Provider\UserProvider
interface, for example.
Entity provider interfaces must extend SyncProviderInterface
. They
don't need to have declared methods, but sync operations can be implemented as
declared methods if desired.
sli
makes it easy to generate a provider interface for an entity:
vendor/bin/sli generate sync provider --magic --op 'get,get-list' 'Acme\Sync\User'
To map entity classes to different provider interfaces (or multiple entities to
one interface, perhaps), you can provide a namespace helper to the entity
store when registering a namespace. See
registerNamespace()
for details and
SyncNamespaceHelper.php for a working example that maps
Acme\Sync\Entity\User
to Acme\Sync\Contract\ProvidesUser
.
To perform a sync operation on an entity, a provider must implement its provider interface and either:
- return a closure for the operation and entity via
getDefinition()
, or - declare a method for the operation using the naming convention below.
In either case, the signature for the implemented operation must be as follows. The first value passed is always the current context and optional arguments may be accepted after mandatory parameters.
Operation1 | Closure signature | Equivalent method2 | Alternative method3 |
---|---|---|---|
CREATE |
fn(SyncContextInterface $ctx, SyncEntityInterface $entity, ...$args): SyncEntityInterface |
create<EntitySingular> |
create_<Entity> |
READ |
fn(SyncContextInterface $ctx, int|string|null $id, ...$args): SyncEntityInterface |
get<EntitySingular> |
get_<Entity> |
UPDATE |
fn(SyncContextInterface $ctx, SyncEntityInterface $entity, ...$args): SyncEntityInterface |
update<EntitySingular> |
update_<Entity> |
DELETE |
fn(SyncContextInterface $ctx, SyncEntityInterface $entity, ...$args): SyncEntityInterface |
delete<EntitySingular> |
delete_<Entity> |
CREATE_LIST |
fn(SyncContextInterface $ctx, iterable $entities, ...$args): iterable |
create<EntityPlural> |
createList_<Entity> |
READ_LIST 4 |
fn(SyncContextInterface $ctx, ...$args): iterable |
get<EntityPlural> |
getList_<Entity> |
UPDATE_LIST |
fn(SyncContextInterface $ctx, iterable $entities, ...$args): iterable |
update<EntityPlural> |
updateList_<Entity> |
DELETE_LIST |
fn(SyncContextInterface $ctx, iterable $entities, ...$args): iterable |
delete<EntityPlural> |
deleteList_<Entity> |
Sync operations are performed within an immutable context created by the provider and replaced as needed to reflect changes to configuration and state. Contents include:
Description | Getter(s) | Setter(s) | Notes |
---|---|---|---|
Provider | getProvider() |
- | |
Service container | getContainer() |
withContainer() |
|
Entity type | getEntityType() |
withEntityType() |
|
Array key conformity | getConformity() |
withConformity() |
|
Entities | getEntities() , getLastEntity() |
pushEntity() |
Tracks nested entity scope. See recursionDetected() . |
Parent entity | getParent() |
withParent() |
Treeable entities only. |
Arbitrary values | hasValue() , getValue() |
withValue() |
|
Operation | hasOperation() , getOperation() |
withOperation() |
withOperation() also sets entity type. |
Filters | hasFilter() ,getFilter() , getFilters() |
withOperation() |
Derived from non-mandatory arguments. See claimFilter() . |
Deferral policy | getDeferralPolicy() |
withDeferralPolicy() |
Applies to nested entity retrieval. |
Hydration policy | getHydrationPolicy() |
withHydrationPolicy() |
Applies to entity relationship retrieval. |
Offline mode | getOffline() |
withOffline() |
(Italicised entries are inherited from ProviderContextInterface
.)
Footnotes
-
See
SyncOperation
. ↩ -
Method names must match either the singular or plural form of the entity's unqualified name. ↩
-
Recommended when the singular and plural forms of a class name are the same. Method names must match the entity's unqualified name. ↩
-
See
withOperation()
for recognised signatures. ↩