phex schreef op vrijdag 19 augustus 2022 @ 04:18:
[...]
Je kan zelf data types maken in Doctrine.
Echter jouw specifieke voorbeeld van decimal bestaat gewoon al en is een string data type in Doctrine zodat je absolute precisie behoudt.
Elke andere oplossing zal ergens die route ook moeten bewandelen. Dat is gewoon een limitatie van PHP dat er geen decimal type bestaat.
Dus je enige optie is dan die string in een custom object type te wrappen.
Het gaat me niet om het type decimal, dat was een voorbeeld. Als je alles op de manier doet zoals veel PHP'ers doen, dan is het ID van de order die je uit een API binnenkrijgt $order["id"] in plaats van $order->id. En de inhoud van dat array-element kan dan een string zijn, of een int, of een fiets, wie zal het weten.
Vervolgens staat er ergens diep in een query-DQL-string "WHERE order_id = :id", in plaats van bijvoorbeeld Linq's .Where(o => o.id == id). En dan wordt het ding ergens aan een form gekoppeld met, je raadt het al, een array van arrays van strings, dus [ "columns" => [ "order_id" => [ "options" => [ ... ] ] ] ].
Het zijn o-ver-al strings. Dat zorgt voor problemen met types en met refactoring.
Deze wist ik niet maar als je er over nadenkt logisch.
Als een ORM gebruikt, dan mapt deze altijd zijn results naar objecten. Dat is immers exact wat elk ORM doet. Een half object maakt dan niet veel sense, want dan is je object mogelijk niet meer valide.
Maar veel gevaarlijker is als je dit object opnieuw persist dan zal alle niet geselecteerde data uit je database verwijderd worden. Immers als je hetzelfde object zou gebruiken is voor het ORM niet te bepalen dat het maar een partial select was.
Dus dan blijven er 2 mogelijkheden over:
- Een ander object type definiëren.
- DBAL gebruiken IPV ORM. Voordeel van deze route is dat de syntax gelijk is aan ORM en je data type mapping in stand blijft. (Dus is een decimal een string by default)
Maar wat ik even niet snap is wat al deze klachten met API/webservices te maken heeft. Vanuitgande dat het een JSON data structuur is, dan heb je daar toch exact hetzelfde probleem in JSON?
Je leest vaker uit een database dan dat je ernaar schrijft, en lezen heeft al snel performanceproblemen als je het over meer dan honderd records en gebruikers hebt en je datalaag niet is gebouwd met performance in het achterhoofd.
De aanname dat je altijd met een heel object werkt, in combinatie met automatische lazy loading van gerelateerde objecten en het feit dat een relationele tabel per definitie nooit plat is maar relaties heeft, zorgt ervoor dat de combinatie van veelgebruikte technieken (Symfony, API Platform, Doctrine) nooit goed kán performen.
Als je een API wil maken die wederom die orders wil exposen met, bijvoorbeeld, een SUM(orderline.quantity), dan gaat die genoemde combinatie van technieken out of the box alle orderregels ophalen per order, en er dan in PHP overheen loopen om de aantallen op te tellen.
Dus dan moet je een custom DataProvider (uit m'n hoofd) schrijven voor API Platform, een custom DTO voor Doctrine (want geen projections), want de aanname van API Platform is dat wat uit je API's komt precies je entities zijn. Dat is om te beginnen al zo'n verschrikkelijk slechte aanname dat ik niet snap dat dat framework zo populair is. Een API-resource is vaak een representatie van een aantal gemapte entities, en zou moeten losstaan van hoe je je data opslaat. Of GraphQL, maar goed.
Einde rant, goedemorgen, koffie?