Waarom je als developer geen Eloquent moet gebruiken
Gepubliceerd: 28 oktober 2019
Ben je benieuwd naar welk alternatief je kunt gebruiken als object relational mapper? Ik vertel je in dit artikel wanneer je als developer wel of niet Eloquent wilt gebruiken in je Laravel applicatie. Als je bekend bent met Laravel dan weet je dat het framework standaard Eloquent https://laravel.com/docs/5.8/eloquent gebruikt als ORM. ORM staat voor object relational mapper. Simpel gezegd biedt het de manier voor de code om te communiceren met de database.
Alternatief voor Eloquent
Bij Create schrijven wij graag unit tests voor onze code. Wij constateerde in een applicatie dat de overhead die nodig was om een Eloquent model te testen/mocken dusdanig hoog was door de nauwe verbinding met de database dat de drempel voor het maken van tests hoger was dan wij naar streven. Daarnaast zijn wij ook een voorstander van het SOLID https://nl.wikipedia.org/wiki/SOLID principe waarbij single responsibility en het open en close principe lastiger te hanteren zijn met Eloquent. Dit komt omdat Eloquent een active record ORM is wat betekent dat je models nauw verbonden zijn met de database en dat je create, read, update, delete (crud) acties verweven zijn met het model. Vanwege deze twee redenen gingen wij kijken of er een alternatief is voor Eloquent en hoe wij deze kunnen implementeren in een bestaande applicatie. Wij kwamen al snel bij Doctrine ORM https://laraveldoctrine.org/docs/current/orm/installation als alternatief.
Voordelen Doctrine
- Type hinten
- Duidelijk inzicht in wat het model bevat en kan
- Makkelijker te testen
- Makkelijker SOLID principe te hanteren
- Bewuste actie van wegschrijven naar database bevordert het nadenken over performance
Voordelen Eloquent
- Laag instapniveau / minder kennis en acties vereist van de ontwikkelaar
- Snellere ontwikkeltijd in kleinere applicaties
Doe eerst research voordat je overstapt naar Doctrine
Voor dat je overstapt naar Doctrine ORM, doe je eerst research naar hoe je gelijktijdig met de huidige ontwikkeling konden implementeren zodat onze klanten hier geen last van ondervinden. Wat bleek is dat het geen enkel probleem is om zowel eloquent models te gebruiken als nieuwe Doctrine models te implementeren voor nieuwe stukken. Op deze manier konden wij langzaam maar zeker de Eloquent models vervangen / deprecated maken. Let wel op dat dit wellicht complexiteit toevoegt in de transitie fase voor beginnende developers omdat er twee orm’s aanwezig zijn in de applicatie. Doctrine is een data mapper ORM waarbij de models zelf niet meer communiceren met de database. Hierdoor zijn ze in principe “plain old php objects” (afgeleid van https://en.wikipedia.org/wiki/Plain_old_Java_object ). De nieuwe models bieden flexibiliteit voor onze klanten bijvoorbeeld in de zin dat ze volledig losstaan van het ORM (open for extension). Daarnaast kunnen wij nu ook de models makkelijk mocken en gebruiken in andere stukken van de code zonder dat wij direct de database benaderen. Een ander voordeel is dat je met Doctrine kan type hinten op je model. Met type hinten weet een developer wat hij/zij met het model kan doen zonder kennis te hebben van de database. In het voorbeeld hieronder zie je bij het eloquent model niet duidelijk welke velden er aan het model hangen. In realiteit bevat de fillable array hieronder namelijk niet alle velden waarop je crud acties kan uitvoeren.
PHP
1<?php
2
3namespace Modules\Employee\Models;
4
5use Illuminate\Database\Eloquent\Model;
6use Illuminate\Database\Eloquent\Relations\BelongsTo;
7use Illuminate\Database\Eloquent\Relations\HasMany;
8use Modules\Core\Traits\Uuids;
9
10class Absence extends Model
11{
12 use Uuids;
13
14 /**
15 * @var string
16 */
17 protected $table = 'employee_absences';
18
19 /**
20 * @var array
21 */
22 protected $fillable = [
23 'start_date',
24 'end_date',
25 'start_time',
26 'end_time',
27 'reason_absence',
28 'reason_declined',
29 'employee_id',
30 'absence_type_id',
31 'whole_day',
32 'status',
33 ];
34}
Daarnaast motiveert Doctrine in veel gevallen performance, omdat het schrijven naar de database niet via een specifieke model loopt maar via een flush method op de entity manager zoals het voorbeeld hieronder.
PHP
1<?php
2
3
4namespace Modules\Api\V2\Controller\Employee;
5
6use App\Entities\Employee;
7use Doctrine\ORM\EntityManager;
8use Modules\Employee\Models\Absence as EloquentAbsence;
9use App\Entities\Absence as DoctrineAbsence;
10
11class AbsenceController
12{
13 /**
14 * @var EntityManager
15 */
16 private $entityManager;
17
18 /**
19 * AbsenceController constructor.
20 * @param EntityManager $entityManager
21 */
22 public function __construct(
23 EntityManager $entityManager
24 ) {
25 $this->entityManager = $entityManager;
26 }
27
28 /**
29 * @return void
30 * @throws \Doctrine\ORM\ORMException
31 * @throws \Doctrine\ORM\OptimisticLockException
32 */
33 public function store(): void
34 {
35 $numbers = [
36 'one',
37 'two',
38 'three'
39 ];
40
41 /** Eloquent way */
42 foreach ($numbers as $number) {
43 $absence = new EloquentAbsence();
44 $absence->employee_id = 1;
45 $absence->save();
46 }
47
48 /** Doctrine way */
49 foreach ($numbers as $number) {
50 $absence = new DoctrineAbsence();
51 $absence->setEmployee(new Employee());
52 $this->entityManager->persist($absence);
53 }
54
55 $this->entityManager->flush();
56 }
57}
58Collapse
Mijn advies voor jou
De problemen met testen en coding principes die wij hadden in onze applicatie worden nu dus opgelost door over te stappen van Eloquent naar Doctrine ORM. Dit betekent echter niet dat je nooit Eloquent moet gebruiken. Een groot voordeel aan Eloquent is dat het makkelijk is in de opstart en gebruik wat het bijvoorbeeld erg geschikt maakt voor een klein/tijdelijke applicatie. Sta dus eerst stil bij de duur en omvang van je applicatie en de test coverage. Is deze groot/hoog dan is Doctrine orm een interessante alternatief om te implementeren.
Er zijn momenteel nog geen opmerkingen geplaatst onder deze blog.
Wil jij als eerste een bericht achter laten?