Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Doctrine Api Client Laravel Package

bankiru/doctrine-api-client

Doctrine-style entity manager for remote RPC APIs. Map entities via YAML, register RPC clients, and use Doctrine Common interfaces (metadata, proxies, repositories) to fetch and manage remote resources as if they were Doctrine entities.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Install the Package:

    composer require bankiru/doctrine-api-client
    
  2. Define an Entity Class: Create a Doctrine entity class with RPC-compatible properties (e.g., MyVendor\Api\Entity\MyEntity).

    namespace MyVendor\Api\Entity;
    
    class MyEntity {
        private $id;
        private $payload;
    
        public function getId() { return $this->id; }
        public function getPayload() { return $this->payload; }
    }
    
  3. Configure Metadata: Create a YAML file (Resources/config/api/MyEntity.api.yml) to map the entity to RPC methods:

    MyVendor\Api\Entity\MyEntity:
      type: entity
      id:
        id:
          type: int
      fields:
        payload:
          type: string
      client:
        name: my-client
        entityPath: my-entity
    
  4. Set Up the EntityManager: Initialize the EntityManager with a custom RpcClient and metadata driver:

    use Bankiru\Api\Doctrine\Configuration;
    use Bankiru\Api\Doctrine\Mapping\Driver\YmlMetadataDriver;
    use Bankiru\Api\Doctrine\Mapping\Driver\MappingDriverChain;
    use Doctrine\Common\Annotations\AnnotationReader;
    use Doctrine\Common\Cache\FilesystemCache;
    use Doctrine\Common\Persistence\Mapping\Driver\SymfonyFileLocator;
    use Doctrine\ORM\EntityManager;
    use Doctrine\ORM\Mapping\Driver\AnnotationDriver;
    use Doctrine\ORM\Mapping\Driver\DriverChain;
    
    $client = new RpcClient(); // Implement RpcClientInterface
    $registry = new ClientRegistry();
    $registry->add('my-client', $client);
    
    $configuration = new Configuration();
    $configuration->setRegistry($registry);
    $configuration->setProxyDir(__DIR__ . '/cache/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);
    
    $entityManager = new EntityManager($configuration);
    
  5. Query Entities: Use the EntityManager to fetch entities via RPC:

    $samples = $entityManager->getRepository(MyEntity::class)->findBy(['payload' => 'sample']);
    foreach ($samples as $sample) {
        echo $sample->getId();
    }
    

First Use Case: Fetching Remote Data as Entities

Leverage the package to treat remote RPC data as local Doctrine entities. For example:

  • Use Case: Fetch user profiles from a legacy RPC service and join them with local data.
  • Implementation:
    1. Define a User entity with RPC-mapped fields.
    2. Configure the EntityManager to point to the RPC client.
    3. Query users via findBy or custom repository methods, and access their data as if it were local.

Implementation Patterns

Workflows

1. Basic CRUD with Doctrine ORM

  • Pattern: Use find(), findBy(), and findOneBy() as you would with a local database.
  • Example:
    $user = $entityManager->getRepository(User::class)->find(1);
    $users = $entityManager->getRepository(User::class)->findBy(['active' => true]);
    
  • Under the Hood: The package translates these calls into RPC requests (e.g., user/find?id=1).

2. Custom Repository Methods

  • Pattern: Extend EntityRepository to add RPC-specific methods.
  • Example:
    class UserRepository extends \Bankiru\Api\Doctrine\EntityRepository {
        public function getActiveUsersWithRoles() {
            $request = new \Bankiru\Api\Rpc\RpcRequest(
                $this->getClientMethod('users-with-roles'),
                ['active' => true]
            );
            return $this->getClient()->invoke([$request])->getResponse($request);
        }
    }
    
  • Configuration: Override the repository class in YAML:
    MyVendor\Api\Entity\User:
      repositoryClass: MyVendor\Api\Repository\UserRepository
    

3. Relationships Between Entities

  • Pattern: Define manyToOne, oneToMany, etc., in YAML to model relationships across RPC services.
  • Example:
    MyVendor\Api\Entity\User:
      manyToOne:
        profile:
          target: MyVendor\Api\Entity\Profile
          inversedBy: users
    
  • Lazy Loading: Relationships are loaded on-demand (e.g., $user->getProfile() triggers an RPC call).
  • Type Hinting: Ensure properties are typed as Entity[]|ArrayCollection for collections.

4. Custom Field Types

  • Pattern: Register custom types for complex RPC payloads (e.g., nested objects, enums).
  • Example:
    $typeRegistry = $configuration->getTypeRegistry();
    $typeRegistry->add('custom_type', new CustomType());
    
  • Use Case: Serialize/deserialize API-specific data (e.g., timestamps, UUIDs).

5. Integration with Laravel

  • Pattern: Bind the EntityManager to Laravel’s service container.
  • Example:
    // In a Laravel service provider
    $this->app->singleton(EntityManager::class, function ($app) {
        $configuration = new Configuration();
        // ... configure as above ...
        return new EntityManager($configuration);
    });
    
  • Usage in Controllers:
    use Illuminate\Support\Facades\App;
    
    $users = App::make(EntityManager::class)
        ->getRepository(User::class)
        ->findBy(['active' => true]);
    

Integration Tips

1. Laravel Service Provider Setup

  • Create a provider to initialize the EntityManager and bind it to the container:
    namespace App\Providers;
    
    use Illuminate\Support\ServiceProvider;
    use Doctrine\ORM\EntityManager;
    
    class DoctrineApiProvider extends ServiceProvider {
        public function register() {
            $this->app->singleton(EntityManager::class, function ($app) {
                $configuration = new Configuration();
                // ... setup configuration ...
                return new EntityManager($configuration);
            });
        }
    }
    
  • Register the provider in config/app.php:
    'providers' => [
        // ...
        App\Providers\DoctrineApiProvider::class,
    ],
    

2. Handling Authentication

  • Pattern: Extend the RpcClient to include auth headers or tokens.
  • Example:
    class AuthRpcClient implements RpcClientInterface {
        private $client;
    
        public function __construct() {
            $this->client = new RpcClient();
            $this->client->setAuthToken('your_token_here');
        }
    
        public function invoke(array $requests) {
            // Add auth headers to each request
            foreach ($requests as $request) {
                $request->addHeader('Authorization', 'Bearer your_token_here');
            }
            return $this->client->invoke($requests);
        }
    }
    

3. Caching RPC Responses

  • Pattern: Cache RPC responses to reduce API calls (e.g., using Laravel’s cache).
  • Example:
    class CachingRepository extends EntityRepository {
        public function find($id) {
            $cacheKey = "api_user_{$id}";
            if (cache()->has($cacheKey)) {
                return cache()->get($cacheKey);
            }
            $user = parent::find($id);
            cache()->put($cacheKey, $user, now()->addHours(1));
            return $user;
        }
    }
    

4. Error Handling

  • Pattern: Wrap RPC calls in try-catch blocks to handle API errors gracefully.
  • Example:
    try {
        $user = $entityManager->getRepository(User::class)->find(1);
    } catch (\Bankiru\Api\Rpc\RpcException $e) {
        Log::error("RPC Error: " . $e->getMessage());
        throw new \RuntimeException("Failed to fetch user data.");
    }
    

5. Testing

  • Pattern: Mock the RpcClient in tests to avoid hitting real APIs.
  • Example:
    use Bankiru\Api\Rpc\RpcClientInterface;
    use Mockery;
    
    $mockClient = Mockery::mock(RpcClientInterface::class);
    $mockClient->shouldReceive('invoke')
        ->andReturn(new \Bankiru\Api\Rpc\Response([['id'
    
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky