In my most recent app I store the id on the record itself. New records have to be identified somehow, since the user can create multiple new records before saving any of them. (My ‘new’ routes look like this: “/contact/new/:id”)
I use negative ids for the new records as an easy way to communicate to the server that the record is new rather than an update. (It would also be possible to put a “new: bool” field on the request sent to the server, or use an enum type for the id itself, but I haven’t yet encountered any issues just using negative ids.)
All new/updated records are sent in a single (combined) request to the server when the user clicks save.
The server keeps track of the newly created ids as new records are inserted, and automatically associates related records that have negative foreign keys with the correct new record.
for contact in request.contacts {
let new_record = insert_record(contact);
id_map.insert(contact.id, new_record.id);
}
for person in request.persons {
if person.contact_id < 0 {
person.contact_id = id_map.get(person.contact_id);
}
let new_record = insert_record(person);
id_map.insert(person.id, new_record.id);
}
It also sends the id_map to the client, which the client uses to patch its local data with the new records from the server.
In my app I haven’t found there to be any difference between new and existing records in terms of their data structure. All fields are used in both cases, and neither case has fields that the other does not. Probably depends on the app or UI, but it works well for me.
I’ve actually used a remote data like type in a previous application. It looked like this:
type RemoteRecord id data
= New data
| Creating data
| Fetching id
| FetchFailed id Error
| Unchanged id data
| Changed id data
I think overall the strategy I described above resulted in simpler code, however. Several different parts of my application need to reference records by ids (data cache, routes, views when linking to other records, …) and it’s better to just always have an id for them to use rather than handling the possibility of there not being one everywhere.
Edit:
Oh, I forgot to mention something that might be relevant. My current app is structured to always have all the data already available for any page within one click of the user’s current view, so that the user is almost never waiting for a network request to complete.
The data is managed by a centralized caching layer, which pretty much eliminated the need for a remote data type like I described above.
Storing an id separate from the record in a remote data type might make more sense if you’re loading each record when the page is loaded. 