You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Should a cloneWith update the id and time fields? #361
I was playing with an example on using the cloneWith method of the CloudEvent class and i noticed that the new returned(cloned) CloudEvent has the same id and time values.
So for example:
const ce = new CloudEvent({....});
ce.toJSON();
// might be something like this:
{
id: 12345,
time: '1:00 pm' // i know that is not the format
}
And then if we wanted to add an extension, for instance, we could clone it into a new cloud event
I wasn't sure if that is correct or not. I can go either way on this. On one hand, it is just a clone with added features, but on the other hand, we are creating a brand new CloudEvent, so should the id and time be recreated?
@lholmquist good question. It might be worth asking in CloudEvents slack channel. My gut is to say that these values should not be cloned - especially the ID.
Not to many responses from the slack channel, other then me and you @lance thinking that those values should be updated wit ha cloneWith and @grant suggesting that we don't have this method, and just let users create a new Cloudevent themselves, which gets around the issue.
Grants suggestion: new CloudEvent({...ce.toJSON(), id: 'new-id'}), which, as he points out is how things are being done internally
We could probably remove the cloneWith, but it would have to be in a major version. i don't remember if there was a reason why we opted for hte clonewith and not just use the contructor again?
Keeping the interface as small as possible is really ideal in the long term. I deal with similar issues across consistency between implementations across 7 implementations with a similar library.
I'm fine with removing the method in 4.0.0 because it's correct that the user can do this themselves. Though frankly, I think it would be better to just deprecate it initially.
But there is one thing I think we should consider changing before that. Even though we eliminated munging the data property, there is still a get() and set() for it because we are checking for binary data, converting it to store in data_base64, and actually storing the data in #_data.
Note that no data attribute exists. That's because there's not actually a data property on the original event. It's a getter/setter pair. This also is unfortunate because when doing console.log(ce), even if an event has data, it won't show. You need to do console.log(ce.toString()).
It's because of this that the implementation of cloneWith() requires the use of toJSON() which, if you look at the code comments, is weird since it doesn't really turn it into JSON. It returns an object. It's just what is used by JSON.stringify() allowing us to jam that data property into the output.
Anyway, this is all a long way of saying I think we should set the data_base64 property in the constructor, eliminate the get()/set() for data property, and deprecate or remove cloneWith(). The only implication is that if a user modifies the data attribute on an existing event by setting it to binary data, the data_base64 property will be either wrong (if there was binary data that got overwritten) or empty (if the original data was not binary).
Anyway, this is all a long way of saying I think we should set the data_base64 property in the constructor, eliminate the get()/set() for data property, and deprecate or remove cloneWith(). The only implication is that if a user modifies the data attribute on an existing event by setting it to binary data, the data_base64 property will be either wrong (if there was binary data that got overwritten) or empty (if the original data was not binary).
It looks like we can break this into a couple workable issues.
remove the getter/setter for data
deprecate cloneWith and remove in a later major release
as for if a user modifies the data, put a warning on the readme when we introduce the change?
Activity
lance commentedon Oct 30, 2020
@lholmquist good question. It might be worth asking in CloudEvents slack channel. My gut is to say that these values should not be cloned - especially the ID.
[-]Should a cloneWith updated the id and time fields?[/-][+]Should a cloneWith update the id and time fields?[/+]lholmquist commentedon Nov 4, 2020
Not to many responses from the slack channel, other then me and you @lance thinking that those values should be updated wit ha cloneWith and @grant suggesting that we don't have this method, and just let users create a new Cloudevent themselves, which gets around the issue.
Grants suggestion:
new CloudEvent({...ce.toJSON(), id: 'new-id'}), which, as he points out is how things are being done internallysdk-javascript/src/event/cloudevent.ts
Line 187 in 1446898
We could probably remove the cloneWith, but it would have to be in a major version. i don't remember if there was a reason why we opted for hte clonewith and not just use the contructor again?
grant commentedon Nov 4, 2020
I suggest not having this method imo.
Keeping the interface as small as possible is really ideal in the long term. I deal with similar issues across consistency between implementations across 7 implementations with a similar library.
lance commentedon Nov 4, 2020
I'm fine with removing the method in 4.0.0 because it's correct that the user can do this themselves. Though frankly, I think it would be better to just deprecate it initially.
But there is one thing I think we should consider changing before that. Even though we eliminated munging the
dataproperty, there is still aget()andset()for it because we are checking for binary data, converting it to store indata_base64, and actually storing the data in#_data.sdk-javascript/src/event/cloudevent.ts
Lines 125 to 134 in 8205bc9
The side effect of this is that simply using an event as the parameter to the constructor doesn't work. You end up losing the
dataproperty.Note that no
dataattribute exists. That's because there's not actually adataproperty on the original event. It's a getter/setter pair. This also is unfortunate because when doingconsole.log(ce), even if an event has data, it won't show. You need to doconsole.log(ce.toString()).It's because of this that the implementation of
cloneWith()requires the use oftoJSON()which, if you look at the code comments, is weird since it doesn't really turn it into JSON. It returns an object. It's just what is used byJSON.stringify()allowing us to jam thatdataproperty into the output.Anyway, this is all a long way of saying I think we should set the
data_base64property in the constructor, eliminate theget()/set()fordataproperty, and deprecate or removecloneWith(). The only implication is that if a user modifies thedataattribute on an existing event by setting it to binary data, thedata_base64property will be either wrong (if there was binary data that got overwritten) or empty (if the original data was not binary).lholmquist commentedon Dec 2, 2020
It looks like we can break this into a couple workable issues.
as for if a user modifies the data, put a warning on the readme when we introduce the change?
github-actions commentedon Jan 2, 2021
This issue is stale because it has been open 30 days with no activity.