bankiru / doctrine-api-client
Doctrine-faced RPC API Client
Installs: 28 822
Dependents: 1
Suggesters: 0
Security: 0
Stars: 8
Watchers: 6
Forks: 1
Open Issues: 5
Requires
- php: ~5.5|~7.0
- doctrine/collections: ~1.3
- doctrine/common: ~2.5
- psr/cache: ~1.0
- psr/log: ~1.0
- scaytrase/rpc-common: ~1.2
- symfony/options-resolver: ~2.3|~3.0
- symfony/property-access: ~2.3|~3.0
- symfony/yaml: ~2.3|~3.0
Requires (Dev)
- phpunit/phpunit: ^4.8.35 | ^5.4 | ^6.0
- symfony/http-kernel: ~2.3|~3.0
Suggests
- psr/cache-implementation: For entity cache support
- psr/log-implementation: For logging support
This package is not auto-updated.
Last update: 2022-11-08 05:03:18 UTC
README
Doctrine-faced RPC Client
Implementation of doctrine\common
interfaces with RPC interfaces (scaytrase\rpc-common
)
Usage
class \MyVendor\Api\Entity\MyEntity { /** @var string */ private $id; /** @var string */ private $payload; public function getId() { return $this->id; } public function getPayload() { return $this->payload; } }
Resources/config/api/MyEntity.api.yml
content:
MyVendor\Api\Entity\MyEntity: type: entity id: id: type: int fields: payload: type: string client: name: my-client entityPath: my-entity
Configure EntityManager
class RpcClient implements RpcClientInterface { /** RpcClient impl */ } $client = new RpcClient(); $registry = new ClientRegistry(); $registry->add('my-client', $client); $configuration = new Configuration(); $configuration->setMetadataFactory(new EntityMetadataFactory()); $configuration->setRegistry($this->registry); $configuration->setProxyDir(CACHE_DIR . '/doctrine/proxy/'); $configuration->setProxyNamespace('MyVendor\Api\Proxy'); $driver = new MappingDriverChain(); $driver->addDriver( new YmlMetadataDriver( new SymfonyFileLocator( [ __DIR__ . '/../Resources/config/api/' => 'MyVendor\Api\Entity', ], '.api.yml', DIRECTORY_SEPARATOR) ), 'MyVendor\Api\Entity' ); $configuration->setDriver($driver); $manager = new EntityManager($configuration);
Call entity-manager to retrieve entities through your api
$samples = $manager->getRepository(\MyVendor\Api\Entity\MyEntity::class)->findBy(['payload'=>'sample']); foreach ($samples as $sample) { var_dump($sample->getId()); }
References
You could reference other API entities via relation annotations. General bi-directional self-reference relation below:
MyVendor\Api\Entity\MyEntity: type: entity id: id: type: int fields: payload: type: string manyToOne: parent: target: MyVendor\Api\Entity\MyEntity inversedBy: children oneToMany: children: target: MyVendor\Api\Entity\MyEntity mappedBy: parent
In order to make *toMany
relations works flawlessly you should define the mapped class property
as Entity[]|ArrayCollection
as hydrator will substitute your relation property with lazy-loading collection interface.
Note on lazy-loading
Generic API is not a DB, so eager reference pre-fetching will always result in additional API query (excluding super-APIs with prefetching features, not supported now), so current implementation always assumes that all requests are extra-lazy. This means that no data will be fetched until you really need it, and you'll have only lazy proxy object before that happens.
Keep it in the mind
Hacking into fetching process
Custom repository
Just call defined RpcClient from your repository
class MyRepository extends \Bankiru\Api\Doctrine\EntityRepository { public function callCustomRpcMethod() { $request = new \Bankiru\Api\Rpc\RpcRequest('my-method',['param1'=>'value1']); $data = $this->getClient()->invoke([$request])->getResponse($request); return $data; } }
Or more portable with mapping
MyVendor\Api\Entity\MyEntity: type: entity id: id: type: int fields: payload: type: string repositoryClass: MyVendor\Api\Repository\MyRepository # This will override repository for MyEntity api: factory: Vendor\Api\CrudsApiFactory client: name: my-client # entityPath: my-entity autoconfigures find and search methods for you as following, but it is not overridable # You can also specify path separator as # entityPathSeparator: "-" # To make autogenerated methods look like my-entity-find methods: find: my-entity\find # find method is mandatory to find calls work search: my-entity\search # find method is mandatory to findBy calls work custom: my-custom-method # do some custom stuff
class MyRepository extends \Bankiru\Api\Doctrine\EntityRepository { public function callCustomRpcMethod() { $request = new \Bankiru\Api\Rpc\RpcRequest( $this->getClientMethod('custom'), ['param1'=>'value1'] ); $data = $this->getClient()->invoke([$request])->getResponse($request); return $data; } }
Custom Cruds API
Custom field types
You could register additional field types to configuration TypeRegistry
(Configuration::getTypeRegistry()
).
Just implement the Type
and register it via TypeRegistry::add('alias', $type)
.
Doctrine ORM types are simple transformers with no real dependencies available but for
this implementation we gone a bit further and make the types DI capable, so you can
register any instance of Type
as type, so it could be DI-enabled service, with any logic
you need
TBD
- No embeddables