bankiru/doctrine-api-client

此包已被废弃,不再维护。未建议替代包。

Doctrine 面向的 RPC API 客户端

2.0 2017-05-12 13:36 UTC

README

Latest Stable Version Total Downloads Latest Unstable Version License

Build Status Scrutinizer Code Quality Code Coverage SensioLabsInsight

Doctrine 面向的 RPC 客户端

使用 RPC 接口(scaytrase\rpc-common)实现 doctrine\common 接口

用法

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 内容

MyVendor\Api\Entity\MyEntity:
  type: entity
  id:
    id:
      type: int

  fields:
    payload:
      type: string
    
  client:
    name: my-client
    entityPath: my-entity

配置 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);    

调用实体管理器通过您的 API 获取实体

$samples = $manager->getRepository(\MyVendor\Api\Entity\MyEntity::class)->findBy(['payload'=>'sample']);
foreach ($samples as $sample) {
   var_dump($sample->getId());
} 

参考

您可以通过关系注解引用其他 API 实体。以下是一般双向自引用关系

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

为了使 *toMany 关系完美工作,您应该将映射类属性定义为 Entity[]|ArrayCollection,因为 hydrator 将用懒加载集合接口替换您的关联属性。

关于懒加载的说明

通用 API 不是一个数据库,所以贪婪引用预取总是会导致额外的 API 查询(不包括具有预取功能的超级 API,目前不支持),所以当前实现始终假设所有请求都是额外懒加载的。这意味着直到您真正需要它们之前,不会获取任何数据,在此之前您将只有懒加载代理对象。

请记住

干预获取过程

自定义仓库

只需从您的仓库调用定义好的 RpcClient

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;
    }
} 

或使用映射更便携

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;
    }
} 

自定义 Cruds API

自定义字段类型

您可以将额外的字段类型注册到配置 TypeRegistryConfiguration::getTypeRegistry())。只需实现 Type 并通过 TypeRegistry::add('alias', $type) 注册它。Doctrine ORM 类型是简单的转换器,没有可用的实际依赖,但在此实现中我们更进一步,使类型支持依赖注入,因此您可以将 Type 的任何实例注册为类型,这样它就可以是 DI 启用的服务,具有您需要的任何逻辑

待定

  • 无嵌入对象