Can I use ORM without connecting entity to a database table
So... am I doing this wrong?
Yes. It doesn't make sense to use the ORM interfaces if you don't really want to use an ORM.
I think the best approach is NOT to think about implementation details at all. Introduce your own interfaces for repositories:
interface Products{ /** * @param string $slug * * @return Product[] */ public function findBySlug($slug);}interface Orders{ /** * @param Product $product * * @return Order[] */ public function findProductOrders(Product $product);}
And implement them with either an ORM:
class DoctrineProducts implements Products{ private $em; public function __construct(EntityManager $em) { $this->em = $em; } public function findBySlug($slug) { return $this->em->createQueryBuilder() ->select() // ... }}
or a Rest client:
class RestOrders implements Orders{ private $httpClient; public function __construct(HttpClient $httpClient) { $this->httpClient = $httpClient; } public function findProductOrders(Product $product) { $orders = $this->httpClient->get(sprintf('/product/%d/orders', $product->getId())); $orders = $this->hydrateResponseToOrdersInSomeWay($orders); return $orders; }}
You can even make some methods use the http client and some use the database in a single repository.
Register your repositories as services and use them rather then calling Doctrine::getRepository()
directly:
services: repository.orders: class: DoctrineOrders arguments: - @doctrine.orm.entity_manager
Always rely on your repository interfaces and never on a specific implementation. In other words, always use a repository interface type hint:
class DefaultController{ private $orders; public function __construct(Orders $orders) { $this->orders = $orders; } public function indexAction(Product $product) { $orders = $this->orders->findProductOrders($product); // ... }}
If you don't register controllers as services:
class DefaultController extends Controller{ public function indexAction(Product $product) { $orders = $this->get('repository.orders')->findProductOrders($product); // ... }}
A huge advantage of this approach is that you can always change the implementation details later on. Mysql is not good enough for search anymore? Let's use elastic search, it's only a single repository!
If you need to call $product->getOrders() and fetch orders from the API behind the scenes it should still be possible with some help of doctrine's lazy loading and event listeners.