Skip to content

Split the Client in a Client and an Entity Repository #15

Closed

Description

@leroy0211

Wouldn't it be nicer to have a default Client which handles the Conversion and persisting, and a separate class like the Doctrine EntityRepository to handle lookups?

If we want to load a specific filter, we can create an EntityRepository and add the specific methods to load something specific. Next add the EntityRepository to the Entity.

If we would want to persist or convert in a different way, we extend the Client and add it to the Entity tell the sdkClient to use a different client

Activity

  1. jdeniau commented on Feb 17, 2016

    @jdeniau
    Member

    Can you write some pseudo-code to see exactly how you see it ?

    I think this is a really good idea because the default client is kind of heavy.

  2. leroy0211 commented on Feb 17, 2016

    @leroy0211
    ContributorAuthor

    Let me see. Something like this (comments are in the code)

    use Mapado\RestClientSdk\Mapping\Annotations as Rest;
    
    /**
     * This way no client (or repository) means the default Client/Repository will be used for lookups
     * The repository will return an object (or array of objects) of Cart when looking up information
     * @Rest\Entity(key="carts")
     */
    class Cart
    {
        /**
         * @Rest\Id()
         */
        protected $id;
    }
    
    
    $cartClient = $sdkClient->getClient(); // this contains the default client (a parameter can give back another client)
    // Multiple clients could be configured in 1 single $sdkClient like https://example.com/api and https://anotherpage.com/api/v2
    $repository = $cartClient->getRepository('carts'); // the client can give back the default Client/Repository
    
    $cart = $repository->find(1); // with a repository you can lookup information
    
    
    // A custom repository
    class CartRepository extends Repository
    {
        public function findByUser(User $user)
        {
            return $this->find($user->getId()); // find is defined in the repository (currently in your AbstractClient)
        }
    }
    
    // the Entity would look like
    /**
     * @Rest\Entity(repository="namespace\to\CartRepository")
     * or with a new annotation like
     * @Rest\EntityRepository("namespace\to\CartRepository")
     */
    class Cart
    {
        /**
         * @Rest\Id()
         */
        protected $id;
    }
    
    // now the code would look exactly the same
    
    $cartClient = $sdkClient->getClient(); // this contains the default client (a parameter can give back another client)
    $repository = $cartClient->getRepository('carts'); // the client will now give the CartRepository back instead of the default Repository
    
    // but now you can use the findByUser on the CartRepository
    $cart = $repository->findByUser($app->getUser()); // with a repository you can lookup information

    Basically the same approach Doctrine uses with EntityRepositories and EntityManager(s)
    With Doctrine another EntityManager can be loaded (for example when you use a different database)

    $em = $doctrine->getEntityManager('products'); // this will lookup in database X
    $repo = $em->getRepository("namespace\to\Product\Entity");
    $product = $repo->findBy(array("id" => 1));
    
    $em1 = $doctrine->getEntityManager('category');  // this will lookup in database Y
    $repo1 = $em1->getRepository("namespace\to\Category\Entity");
    $categories = $repo1->findByProduct($product);
    
    $defaultrepo = $doctrine->getEntityManager()->getRepository("namespace\to\User\Entity"); // this will lookup in your default database
    $user = $defaultrepo->find(1);
  3. jdeniau commented on Feb 18, 2016

    @jdeniau
    Member

    In fact, you can manage multiple endpoints too when using the bundle:

    You can configure something like this:

    # app/config/config.yml
    mapado_rest_client_sdk:
        entity_managers:
            foo:
                server_url: 'http://foo.com:8080'
                mappings:
                    prefix: /v1
                    dir: '%kernel.root_dir%/../src/Foo/Entity/'
            bar:
                server_url: 'http://bar.com'
                mappings:
                    dir: '%kernel.root_dir%/../src/Bar/Entity/'

    You will have too clients: mapado.rest_client_sdk.foo and mapado.rest_client_sdk.bar, which is pretty similar to the doctrine differents entity managers. (in fact the doctrine bundle allows you to call doctrine.orm.foo_entity_manager and doctrine.orm.bar_entity_manager).

    You have a point though about the component, which does not have a main container.

  4. jdeniau commented on Mar 11, 2016

    @jdeniau
    Member

    Fixed in #21

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions