使用Doctrine 2将实体保存到REST API而不是DB [英] Save entities to a REST API instead of DB using Doctrine 2

查看:89
本文介绍了使用Doctrine 2将实体保存到REST API而不是DB的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这与我的其他问题有关:使用REST API持久化实体

This is related to my other question: Persisting entities using a REST API.

对于Symfony2中的项目,我需要使用远程(第三方)RESTful API 持久化实体。我也希望能够使用该API的数据来检索实体。

For a project in Symfony2 I need to be able to persist entities using an remote (third-party) RESTful API. I also want to be able to retrieve entities with data from that API.

换句话说,我的对象被保存在第三方数据库。他们不是保存在我自己的数据库中。每当我需要保存数据或查找数据时,我使用他们的REST API。

In other words, my objects are saved in the third-party database. They are not saved in my own database. Whenever I need to save data, or find data, I use their REST API.

我已经指向了几个库,包括由Doctrine本身制作的一个。但是,他们中没有人向我提供我正在寻找的东西。由Doctrine制作的是最好的选择,但使用活动记录模式,并不提供所有甜美的Doctrine 2的东西。不要误会,我一直在使用Active Record实现很长一段时间,但我现在已经爱上了Doctrine的Data Mapper模式。

I have been pointed to several libraries, including one made by Doctrine itself. However, none of them offers me what I'm looking for. The one made by Doctrine is the best option, but uses the Active Record pattern and doesn't offer all the sweet Doctrine 2 stuff. Don't get me wrong, I've been using Active Record implementations for a long time, but I've fallen in love with Doctrine's Data Mapper pattern now.

理想情况我希望能够使用Doctrine的ORM,并且只需使用API​​调用保存实体的逻辑替换特定于数据库的部分。 (当然也可以使用相同的API来检索它们)。这样我可以使用大致相同的语法来保存我的实体:

Ideally, I'd like to be able to use Doctrine's ORM and simply replace the database-specific part with logic that saves entities using an API call. (and of course retrieves them using that same API). This way I can save my entities using roughly the same syntax:

// current way to save $entity in database:
$em = $this->getDoctrine()->getManager();
$em->persist($entity);
$em->flush();

// desired way to save $entity using REST API:
// (just an example, it doesn't have to be exactly like this)
$em = $this->getDoctrine()->getManager('rest');
$em->persist($entity);
$em->flush();

请注意,我不是要自己建立API,我只是试图与第三方API,以保存我的实体。我对于教条来说比较新,但我很喜欢这个。我真的很喜欢从实体中分离持久化逻辑的想法,但到目前为止,我无法找到如何使用它来使用API​​来保存它们。

Note that I'm not trying to build my own API, I'm simply trying to communicate with a third party API in order to save my entities. I'm relatively new to Doctrine, but I'm liking it so far. I really like the idea of seperating the persistence logic from the entities, but so far I can't find out how I can use that to save them using an API.

Symfony的文档中有一篇文章,描述了如何使用多个实体经理。我正在寻找类似于此的解决方案,但使用实体经理,我可以使用REST而不是DB。

There is an article in Symfony's documentation, describing how to work with multiple Entity Managers. I'm looking for a solution similar to this, but with an entity manager that enables me to use REST instead of the DB.

我一直在试图调整Doctrine的ORM我自己,但是我最终只能重写一半的代码,因为它(似乎)与数据库特定的逻辑太紧密相连。我可能会做一些愚蠢的事情。

I've been trying to tweak Doctrine's ORM myself, but I only end up rewriting half their code because it (seems to be) too tightly coupled to the Database-specific logic. I might be doing something stupid of course.

所以我的问题是,有一种方法来替换/覆盖Doctrine的ORM的数据库特定部分那些?没有重写很多应该对所有持久性方法都是常见的事情?以前是否已经完成?或者根本不可能,因为Doctrine旨在与数据库一起使用,并且对于其他用途不够灵活。

So my question is, is there a way to replace / override the database-specific parts of Doctrine's ORM with custom ones? Without rewriting a lot of things that should be common for all persistence methods? Has it been done before? Or is it simply not possible because Doctrine is intended for use with a database and isn't flexible enough for other uses?

CakePHP似乎可以这样做,通过让你定义一个自定义的 DataSource 。这样,您可以使用SQL数据库保存模型,还可以使用API​​,会话等。我想做大致相同,但是使用Doctrine而不是CakePHP。

CakePHP seems to be able to do this, by letting you define a custom DataSource. This way you can save your models using an SQL database, but also using an API, sessions, etc. I want to do roughly the same, but using Doctrine instead of CakePHP.

实际的数据库查询似乎由
Doctrine\ORM\Persisters\BasicEntityPersister class 。还有几个其他的xxxPersister类来处理不同类型的继承。可能用我们自己的替换xxxPersister类,所以我们可以用REST API代码替换DB代码。

The actual database queries seem to be executed by the Doctrine\ORM\Persisters\BasicEntityPersister class. There are several other xxxPersister classes, to deal with different types of inheritance. It might be possible to replace the xxxPersister classes with our own, so we can replace the DB code with REST API code.

持久化对象是在 getEntityPersister()方法 Doctrine\ORM\UnitOfWork 类。类名被硬编码,所以我们需要覆盖 Doctrine\ORM\UnitOfWork ,如果我们想使用我们自己的persisters。

The persister objects are created within the getEntityPersister() method of the Doctrine\ORM\UnitOfWork class. The classnames are hardcoded so we need to override Doctrine\ORM\UnitOfWork if we want to use our own persisters.

Doctrine\ORM\UnitOfWork 似乎被硬编码成 Doctrine\ORM\EntityManager ,所以我们也需要覆盖那个。但是,这个类似乎包含一些数据库特定的部分。例如,它的构造函数需要一个 Doctrine\DBAL\Connection 对象作为参数。也许最好创建自己的EntityManger(实现 Doctrine\Common\Persistence\ObjectManager 接口),只要这不花费太多的时间/精力

Doctrine\ORM\UnitOfWork seems to be hardcoded into Doctrine\ORM\EntityManager, so we need to override that one as well. However, this class seems to contain some database-specific parts. For instance, it's constructor requires a Doctrine\DBAL\Connection object as parameter. Perhaps it's better to create our own EntityManger (implementing the Doctrine\Common\Persistence\ObjectManager interface), as long as that doesn't take too much time / effort.

用于检索/加载/查找对象的数据库特定代码位于同一个类中作为持久/删除等的代码: Doctrine\ORM\Persisters\xxxPersister 类。所以如果我们可以用自己的替代它们,为了保持对象,我们也可以检索对象。例如,当您调用 $ entityRepository-> findAll()时,它将返回 $ entityRepository-> findBy(array())(因为 findAll()只是 findBy(array())的别名,运行以下代码:

The database-specific code for retrieving/loading/finding objects lives in the same class as the code for persisting / deleting etc: the Doctrine\ORM\Persisters\xxxPersister classes. So if we are able to replace them with our own, in order to persist objects, we can retrieve objects as well. When you call $entityRepository->findAll(), for instance, it will return $entityRepository->findBy(array()) (because findAll() is simply an alias for findBy(array())) which will run the following code:

$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);

return $persister->loadAll($criteria, $orderBy, $limit, $offset);

换句话说,一旦我们得到 EntityManager 要创建正确的 UnitOfWork xxxPersister 对象,我们将能够使用 find 方法在 EntityRepository

In other words, once we get EntityManager to create the right UnitOfWork and xxxPersister objects, we will be able to use the find methods in the EntityRepository.

我发现为Doctrine开发了一个新功能: custom persisters (另见 this )。这样可以更容易地使用自定义的persister类。我还不知道是否能够创建一个非DB持久性,但它看起来很有前途。不过最近的更新是在8月份,所以我不确定是否还在积极的发展。

I discovered that a new feature is developed for Doctrine: custom persisters (also see this). This should make it easier to use a custom persister class. I don't know yet if it will enable us to create a non-DB persister, but it looks promising. However, the last updates were in August, so I'm not sure if it's still in active development.

推荐答案

使用解决方案不可用,我决定写我自己的。我打电话给它 RAPL 。它受到Doctrine的ORM的极大启发(实际上它使用了由Doctrine Common提供的许多接口)。

As a ready-to-use solution wasn't available, I decided to write my own. I called it RAPL. It's heavily inspired by Doctrine's ORM (in fact, it uses many of the interfaces provided by Doctrine Common).

使用RAPL我可以简单地编写一个小的YAML文件来配置我的实体和Web服务之间的映射,允许我使用定制的EntityManager来保存/检索实体。

Using RAPL I can simply write a small YAML file to configure the mapping between my entities and the web service, allowing me to persist/retrieve entities using the custom EntityManager.

这篇关于使用Doctrine 2将实体保存到REST API而不是DB的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆