-
-
Notifications
You must be signed in to change notification settings - Fork 846
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow DataPersister to return a new instance instead of mutating #1967
Allow DataPersister to return a new instance instead of mutating #1967
Conversation
a73fad3
to
1723b86
Compare
I hope, I have not forgotten any |
@@ -58,7 +58,9 @@ public function onKernelView(GetResponseForControllerResultEvent $event) | |||
|
|||
switch ($request->getMethod()) { | |||
case 'POST': | |||
$objectManager->persist($controllerResult); | |||
$event->setControllerResult( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CS: We usually don't split into multiple lines like this... Just keep it in one line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I won’t argue on CS, but in this case, given the low visual impact of ??
, I fear that relegating the ??
at the end of the line somehow hides what’s going on.
For instance, to me, this is far less self-explanatory than the splitted version.
case 'POST':
$event->setControllerResult($this->dataPersister->persist($controllerResult) ?? $controllerResult));
break;
As I said, this will be my only point of view on CS, I wont argue furthermore if you want to stick to the one line version ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nevermind, adding the deprecation notice forces me to assign persist result to a temp var anyway, so the one line will be of fine size 👍
src/EventListener/WriteListener.php
Outdated
@@ -50,7 +50,10 @@ public function onKernelView(GetResponseForControllerResultEvent $event) | |||
case 'PUT': | |||
case 'PATCH': | |||
case 'POST': | |||
$this->dataPersister->persist($controllerResult); | |||
$event->setControllerResult( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CS: We usually don't split into multiple lines like this... Just keep it in one line.
@@ -33,6 +33,8 @@ public function supports($data): bool; | |||
* Persists the data. | |||
* | |||
* @param mixed $data | |||
* | |||
* @return object|void Void will not be supported in API Platform 3, an object should always be returned |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it might be better if we add deprecation errors where this method is called in API Platform?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added a deprecation notice in the WriteListener
, and ItemMutationResolverFactory
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing it in ChainDataPersister
should be enough. If we deprecate returning void
, please remove it from the supported types and only keep it in the comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok you already made the changes, so keep them :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doing it in ChainDataPersister should be enough.
It's not enough because ChainDataPersister
is only an implementation which might or might not be used by the user.
435ad99
to
6056ad5
Compare
Thanks for your review @teohhanhui 👍 , code updated :) |
$dummy->setName('Dummyrino'); | ||
|
||
$dummy2 = new Dummy(); | ||
$dummy2->setName('Dummyferoce'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Dummycorn
🦄 ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
@teohhanhui please merge after taking a last quick look :) thanks! |
@gorghoa Looks like we need a rebase to merge. 👍 |
6056ad5
to
96a6148
Compare
96a6148
to
5f050fe
Compare
Thanks @gorghoa! 🎉 |
Thank you all for your kind reviews and making api platform always better! 💪 |
@@ -51,7 +51,7 @@ public function persist($data) | |||
{ | |||
foreach ($this->persisters as $persister) { | |||
if ($persister->supports($data)) { | |||
$persister->persist($data); | |||
return $persister->persist($data) ?? $data; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I know it's a bit late, but wouldn't this prevent all persisters to run, and wouldn't this stop at the first persister that supports this data ? what if I need to apply multiple data persisters ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good catch... We may return after the loop instead of inside. WYT? (ping @gorghoa)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
indeed, nice catch… Thanks @Taluu for your review!
We may return after the loop instead of inside. WYT?
But from which persister shall we return? First one? Last one? Custom strategy based on priority? (somehow, this question was in fact already valid with the former implementation: the last was the winner, but was it “safe” to assume it was the one that should win the refresh battle?).
I’m now ashamed that my implementation causes two BC breaks:
- 1st, as @Taluu found out, it skips other registered persisters
- 2nd. It changes the refresher order
Maybe the best option in term of confidence should be not return data from persister but somehow re-trigger a read item operation. At the cost of an extra read query.
afterthoughts:
This may fix everything…
re-assign $data
to the previous persister returned value, then return $data
outside the loop as @dunglas suggests.
foreach ($this->persisters as $persister) {
if ($persister->supports($data)) {
$data = $persister->persist($data) ?? $data;
}
}
return $data;
Everything should be as before 🎉
ps. I would personally rather have a recursive function instead of re-assigning $data
in the loop, but I’ve the feeling that we could lose some perfs + inconsistent coding style :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
afterthoughts
It was exactly what i've in mind (last win)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, that's what I had in mind too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
closes #1799
DataPersisterInterface
can now return the result of the persistence call instead of relying on data mutation. Thus allowing persistence layer to deal with immutable data.At least, this PR breaks the technical detail that was implicitly using objects instance reference as an identifier for an entity, and conceptually I find this a huge win :)