Add support for ignoring client generated IDs
Solves issue #48
Added configurable client_id_prefix parameter which is taken into consideration when parsing parameters.
All IDs starting with client_id_prefix will be ignored.
This feature gives you the option to create new AND update existing nested records on parent update.
{
"type": "multitracks",
"attributes": {
"title": "Multitrack"
},
"relationships": {
"tracks": {
"data": [
{
"type": "tracks",
"id": "123" // Existing ID for existing resources
},
{
"type": "tracks",
"id": "cid_new_track" // Client ID for new resources -> needs to match ID in included below
}
]
}
},
"included": [
{
"id": "123", // Existing ID for existing resources
"type": "tracks",
"attributes": {
"name": "Piano"
}
},
{
"id": "cid_new_track", // Client ID for new resources -> needs to match ID in relationships below
"type": "tracks",
"attributes": {
"name": "Drums"
}
}
]
}
params.from_jsonapi
{
"multitrack" => {
"title" => "Multitrack",
"tracks_attributes" => {
"0" => {
"id" => "123",
"name" => "Piano"
},
"1" => { // No ID is present, so ActiveRecord#update correctly creates the new instance
"name" => "Drums"
}
}
}
}
Thanks for your opinion @greena13
I would add some additional information
Instead of cid_ prefix in examples, we should use lid_ as it is stated in draft of json api 1.1 (draft but still better than custom 😄 ) https://jsonapi.org/format/1.1/#document-resource-object-identification
I think it's fair point to disable it as default for backward compatibility.
And we thought about renaming prefix to ignore_ids_with_prefix, but @greena13 @ignore_id_filter is also good.
I am not sure if we should provide lambda, such elasticity is not needed probably.
What do you think issue#48 participants❔ 🎛️
I'm happy with any of the possibilities you've outlined.
The minimal set of changes appears to be changing from cid_ to lid_ (with it being part of the draft standard, I rescind any concerns about introducing "breaking changes" that could not be disabled, and would probably just suggest a major increment instead).
Actually, we have some legacy clients for which the breaking change of moving from cid_ to lid_ would present a problem.
Retaining the ability to specify an alternative prefix would remain very valuable for us.
Thanks for your comments and suggestions 👍
I think the best solution is the one @greena13 provided, with setting a default client_id_prefix to nil and checking if it's defined.
I also like the ignore_ids_with_prefix config name instead of client_id_prefix.
Regarding the lambda, I'm not sure if it's needed here. I think having the prefix config option is good enough, but if you insist, we could add a lambda filter as well.
Regarding the lambda, I'm not sure if it's needed here. I think having the prefix config option is good enough, but if you insist, we could add a lambda filter as well.
To help focus the remaining conversation, I'll rescind my original suggestion for a lambda (it won't currently serve our needs and if absolutely needed, consumers of the library can override the appropriate method - as one would expect when deviating from the intended usage of a library).
@nikajukic have there been any updates on this since last month?
@greena13 actually we should use lid as local id key instead of id with the prefix according to draft.
it solves some problems but requires some additional changes for frontend.
How do you see that change ?
@choosen this is a very good point and a distinction that was somehow missed (did the proposal change, or was I just not attentive enough the first time?)
I would imagine at first thought, using a additional id field to match resources on (but then discard it) would be a different approach/algorithm that should be done independently and regardless of this issue.
But then we still have this separate issue of wanting to migrate legacy clients that use a value prefix to determine local only IDs. It doesn't perhaps feel like it should be part of the critical functionality of the gem, but is there some way of separating out the algorithm for including ids into a method or module that can be easily extended and overridden, so we could provide users with instructions on how to support this legacy workaround if needed?
@greena13 @choosen sorry for the late response and feature update.
I've applied the changes you wanted:
- renamed client_id_prefix to ignore_ids_with_prefix
- set default value for ignore_ids_with_prefix config to nil
- updated tests
Can you please check how does it look now?
@greena13 what do you think ?
Thanks @nikajukic and @choosen . This looks good to me as a solution to the problem as originally stated, and this will likely prove a valuable tool for consumers of the library looking to upgrade or move to something more standard.
However, long term, I expect to move to a lid (separate attribute) based solution. Although waiting for the specification to exit draft status, and/or all of the various serialisation/deserialisation libraries used in the particular stack I'm working with, to support it, will take some time yet.
So 👍 as a likely useful stop-gap in the interim, and possibly for other uses I haven't anticipated in the long term.
JSON:API v1.1 was finalized September 30, 2022! 🎉 CC: @greena13