Dies hängt mit meiner anderen Frage zusammen: Persistente Entitäten, die eine REST-API verwenden.
Für ein Projekt in Symfony2 muss ich in der Lage sein, Entitäten zu speichern Verwenden einer Remote-RESTful-API (Drittanbieter).. Ich möchte auch in der Lage sein, Entitäten mit Daten von dieser API abzurufen.
Mit anderen Worten, Meine Objekte werden in der Datenbank des Drittanbieters gespeichert. Sie sind nicht in meiner eigenen Datenbank gespeichert. Wann immer ich Daten speichern oder Daten finden muss, verwende ich ihre REST-API.
Ich wurde auf mehrere Bibliotheken hingewiesen, darunter eine, die von Doctrine selbst gemacht wurde. Aber keiner von ihnen bietet mir, was ich suche. Das von Doctrine hergestellte ist die beste Option, verwendet jedoch das Active Record-Muster und bietet nicht all das süße Doctrine 2-Zeug. Verstehen Sie mich nicht falsch, ich verwende seit langem Active Record-Implementierungen, aber jetzt habe ich mich in das Data Mapper-Muster von Doctrine verliebt.
Idealerweise möchte ich das ORM von Doctrine verwenden und einfach den datenbankspezifischen Teil durch Logik ersetzen, die Entitäten mithilfe eines API-Aufrufs speichert. (und ruft sie natürlich mit derselben API ab). Auf diese Weise kann ich meine Entitäten mit ungefähr derselben Syntax speichern:
// 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();
Beachten Sie, dass ich nicht versuche, meine eigene API zu erstellen, sondern einfach versuche, mit einer Drittanbieter-API zu kommunizieren, um meine Entitäten zu speichern. Ich bin relativ neu in Doctrine, aber bisher gefällt es mir. Ich mag die Idee, die Persistenzlogik von den Entitäten zu trennen, aber bisher kann ich nicht herausfinden, wie ich sie verwenden kann, um sie mithilfe einer API zu speichern.
Es gibt einen Artikel in der Symfony-Dokumentation, der beschreibt wie man mit mehreren Entity Managern arbeitet. Ich suche nach einer ähnlichen Lösung, aber mit einem Entitätsmanager, der es mir ermöglicht, REST anstelle der DB zu verwenden.
Ich habe versucht, das ORM von Doctrine selbst zu optimieren, aber am Ende schreibe ich nur die Hälfte ihres Codes neu, weil es (scheint) zu eng mit der datenbankspezifischen Logik gekoppelt ist. Ich könnte natürlich etwas Dummes tun.
Also meine Frage ist, Gibt es eine Möglichkeit, die datenbankspezifischen Teile des ORM von Doctrine durch benutzerdefinierte Teile zu ersetzen / zu überschreiben?? Ohne viele Dinge neu zu schreiben, die für alle Persistenzmethoden gleich sein sollten? Wurde es schon einmal gemacht? Oder ist es einfach nicht möglich, weil Doctrine für die Verwendung mit einer Datenbank vorgesehen ist und für andere Anwendungen nicht flexibel genug ist?
Mein eigener Fortschritt
CakePHP scheint dazu in der Lage zu sein, indem es Sie einen Benutzerdefiniert definieren lässt Datenquelle. Auf diese Weise können Sie Ihre Modelle mit einer SQL-Datenbank speichern, aber auch mit einer API, Sitzungen usw. Ich möchte ungefähr dasselbe tun, aber mit Doctrine anstelle von CakePHP.
Aktualisierung 1
Die eigentlichen Datenbankabfragen scheinen von der ausgeführt zu werden
Doctrine\ORM\Persisters\BasicEntityPersister
Klasse. Es gibt mehrere andere xxxPersister-Klassen, um mit verschiedenen Arten der Vererbung umzugehen. Es ist möglicherweise möglich, die xxxPersister-Klassen durch unsere eigenen zu ersetzen, sodass wir den DB-Code durch den REST-API-Code ersetzen können.
Die Persister-Objekte werden innerhalb der erstellt getEntityPersister()
Methode der Doctrine\ORM\UnitOfWork
Klasse. Die Klassennamen sind fest codiert, daher müssen wir sie überschreiben Doctrine\ORM\UnitOfWork
wenn wir unsere eigenen Persister verwenden wollen.
Aktualisierung 2
Doctrine\ORM\UnitOfWork
scheint fest einprogrammiert zu sein Doctrine\ORM\EntityManager
, also müssen wir auch diesen überschreiben. Diese Klasse scheint jedoch einige datenbankspezifische Teile zu enthalten. Zum Beispiel benötigt der Konstruktor a Doctrine\DBAL\Connection
Objekt als Parameter. Vielleicht ist es besser, einen eigenen EntityManager zu erstellen (Implementierung der Doctrine\Common\Persistence\ObjectManager
Schnittstelle), solange das nicht zu viel Zeit / Aufwand kostet.
Aktualisierung 3
Der datenbankspezifische Code zum Abrufen/Laden/Finden von Objekten befindet sich in derselben Klasse wie der Code zum Persistieren/Löschen usw.: the Doctrine\ORM\Persisters\xxxPersister
Klassen. Wenn wir also in der Lage sind, sie durch unsere eigenen zu ersetzen, können wir zum Persistieren von Objekten auch Objekte abrufen. Wenn du anrufst $entityRepository->findAll()
zum Beispiel wird es zurückkehren $entityRepository->findBy(array())
(Weil findAll()
ist einfach ein Alias für findBy(array())
), die den folgenden Code ausführt:
$persister = $this->_em->getUnitOfWork()->getEntityPersister($this->_entityName);
return $persister->loadAll($criteria, $orderBy, $limit, $offset);
Mit anderen Worten, sobald wir bekommen EntityManager
Recht zu schaffen UnitOfWork
und xxxPersister
Objekte, werden wir in der Lage sein, die zu verwenden find
Methoden in der EntityRepository
.
Aktualisierung 4
Ich habe entdeckt, dass eine neue Funktion für Doctrine entwickelt wird: benutzerdefinierte Persister (siehe auch Dies). Dies sollte es einfacher machen, eine benutzerdefinierte Persister-Klasse zu verwenden. Ich weiß noch nicht, ob es uns ermöglichen wird, einen Nicht-DB-Persister zu erstellen, aber es sieht vielversprechend aus. Die letzten Updates waren jedoch im August, daher bin ich mir nicht sicher, ob es sich noch in der aktiven Entwicklung befindet.
Verwenden Sie das FOSRESTBundle?
– Michael Villeneuve
12. Dezember 2013 um 23:40 Uhr
Nein. Ich möchte keine eigene API erstellen. Ich möchte meine Entitäten mit einer vorhandenen Drittanbieter-API beibehalten.
– Nic Wortel
12. Dezember 2013 um 23:42 Uhr
Können Sie ein konkreteres Beispiel für diese Aussage geben? “Ich würde gerne das ORM von Doctrine verwenden und einfach den datenbankspezifischen Teil durch Logik ersetzen, die Entitäten über einen API-Aufruf speichert.” Es gibt etwas, das mir fehlen muss. Denn bevor Sie Ihre Daten an Ihre DB übermitteln, können Sie damit machen, was Sie wollen.
– Michael Villeneuve
12. Dezember 2013 um 23:50 Uhr
Ja, sorry, ich hätte deine andere Frage lesen sollen, jetzt verstehe ich viel besser, was du zu tun versuchst. Ich werde versuchen, es herauszufinden, scheint eine sehr interessante Frage zu sein.
– Michael Villeneuve
12. Dezember 2013 um 23:55 Uhr
Kein Problem, ich glaube, meine Frage ist nur etwas vage. Es sollte klar sein, ohne die andere Frage zu lesen. Trotzdem danke für deine Zeit und Mühe. Wenn Sie etwas finden, lassen Sie es mich wissen!
– Nic Wortel
12. Dezember 2013 um 23:58 Uhr