I have an Agenda
that holds many Card
, and a Card
has multiple DetailItem
that hold a value like Email
, Phone
and a Label
So, I can do:
agenda = new Agenda()
oneCard = new Card()
item = new DetailItem(new Email("x@y.z"), new Label("Work")
oneCard.addItem(item)
agenda.addCard(oneCard)
By rule, there can only be one DetailItem
with an Email
instance with "x@y.z" value, so if you try to add a new item with that data it will raise an exception.
This seems to be ok until I try to update a DetailItem
. I can't find a way that I feel comfortable with.
I try to think in terms of business model and not implementation details, but I cannot leave them off for a long, and they enter the domain I like it or not.
The thing is that I will have a REST interface, and I have two ways of doing things.
- Send a PUT to
/cards/<cardId>
with adetailItems' array, fetch the
Cardby ID, create a new
Cardwith the new data provided in the PUT, and sync the current
Card` with the new one. - Send a PUT to /cards//items/, fetch the
Card
, find theDetailItem
, and update it the same way in option 1
If I go with option 1, I have to remove all DetailItem
from current Card
that don't exists in the new one. That leads with some INSERT queries produced by the ORM, and some DELETES. No UPDATE at all.
If I go with option 2, I will have many PUTs to change multiple items, which is not performant at all, and it will lead me to introduce an ID field to the DetailItem
so I can identify them, which introduces something is not part of the domain!.
The only option I found was to go with option 1, and send a request like this:
{
...
detailItems: [
{
type: "email",
oldValue: "x@y.z",
oldLabel: "Work",
newValue: "a@b.c",
newLabel: "Work",
}
]
}
So I can do something like this:
card = agenda.getCardIdentifiedBy(the_identifier)
for(itemUpdate in jsonData.detailItems)
itemClass = ValueClassMapper.from(itemUpdate.type) // "email" -> Email
oldItem = new DetailItem(new itemClass(itemUpdate.oldValue), new Label(itemUpdate.oldLabel))
newItem = new DetailItem(new itemClass(itemUpdate.newValue), new Label(itemUpdate.newLabel))
card.updateItemWith(oldItem, newItem)
But, I don't know, maybe I have a wrong abstraction Can anyone help? Thanks in advance!