-
Notifications
You must be signed in to change notification settings - Fork 133
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
Remotely generate IDs #849
Comments
You are correct about options 1 and 2. And option 3 should be possible if all your records are created server-side and none in your client. This might be the case if you are only querying records from the server for instance. If you are creating records client-side, then Orbit's transform builder will verify that IDs are assigned to those records and, if not, auto-generate an v0.17 beta simplifies the process of using server-generated URLs of any kind for individual records, since URLs that come in a let latestRecord = memory.query(q => q.findRecord(record), { url: record.links.self }); v0.17 also makes it a bit easier to work with remote keys. You should just be able to define a key for each model that uses it in your schema, and then the JSONAPISource will recognize and use that key (no need to customize let latestRecord = memory.query(q => q.findRecord({ type, key, value }); With that said, I'm just now wrapping up a PR to bring some of this goodness to ember-orbit, but I can keep you posted. |
I guess what I'm finding surprising is that remote IDs are relegated to a behind-the-scenes concern while local IDs are front-and-center. I would have thought that local IDs are of interest only to Orbit and its sources, while app code almost always wants to talk about remote IDs. From the app author's perspective, it's a bug to render a local ID in a user-facing URL: <a href="/posts/{{this.model.id}}/detail"> What am I supposed to say instead in this spot? Likewise for queries, it would be a bug to ever pass a local ID to findRecord, if there's any chance that the request will be sent to the server: model({ post_id }) {
return this.store.query(q => q.findRecord({ type: 'price', id: post_id }));
} So instead all queries needs to be against the remote ID. How does one spell that? I don't understand your model({ post_id }) {
return this.store.query(q => q.findRecord({ type: 'price', key: 'remoteId', value: post_id }));
} |
As I understood it, it is actually a good idea to do operations on local ids. Remote ids will be used for url generation, for queries from a url, for displaying the id to the user, and I believe that's it. |
@SafaAlfulaij yes, thanks for concisely summarizing this.
@ef4 As you point out in the issue, option 1 (a single With that said, I realize that this can feel a bit inverted and prone to error coming from an exclusively server-generated ID world, especially in v0.16. I've worked to improve the ergonomics with ID management recently, so that things are simpler and can Just Work at any layer in v0.17 regardless of your ID strategy. For instance, querying by key or id, improved normalizers, serializers, etc. Arguably, the flexible model({ post_id }) {
- return this.store.query(q => q.findRecord({ type: 'price', key: 'remoteId', value: post_id }));
+ return this.store.query(q => q.findRecord({ type: 'price', remoteId: post_id }));
} An alternative approach that might seem more intuitive for server-generated-id scenarios would be to rename One last consideration in my internal debates here is a simplification of relationship data tracking -- if an application can guarantee that IDs are universally unique across types, then we can track normalized relationship data with a single ID instead of a {
type: 'planet',
id: '4d6ad6eb-3a63-433c-a06f-93ba78c8ad1a',
attributes: {
name: 'Jupiter'
},
relationships: {
moons: {
data: [
- { type: 'moon', id: '53e02af4-ac24-47e1-8f8f-885ca7dc95be' },
- { type: 'moon', id: '1c72c694-8f5e-4a4e-a446-963e12db8175' }
+ '53e02af4-ac24-47e1-8f8f-885ca7dc95be',
+ '1c72c694-8f5e-4a4e-a446-963e12db8175'
]
}
}
} I'm just laying all this out there as it's all related to Orbit's rationale for record identity and the remaining questions are perhaps the most important ones to settle prior to v1.0. Of course, feel free to ignore most of this for now while you focus on getting your app up and running with the current approach :) |
This was the first thing I tried, but maybe I am missing some setup step because my models don't have What is the appropriate extension point to make that happen? |
Also, I'm hearing the subtext "don't use 0.16", which is fine but consider making that discoverable somehow. Everything currently pushes adopters to 0.16. |
Oops, it's |
I also tried keys.remoteId, I also don’t have that.
…On Sat, Jun 12, 2021 at 10:38 AM Safa Alfulaij ***@***.***> wrote:
For url generation, we can use the remote id directly (this.modal.remoteId
)
This was the first thing I tried, but maybe I am missing some setup step
because my models don't have this.model.remoteId.
What is the appropriate extension point to make that happen?
Oops, it's this.model.keys.remoteId, sorry. I have a proxy around the
model data and got confused...
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#849 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACN6MQQTFNLXMHDG4RLEWLTSNWQFANCNFSM46RT43XA>
.
|
To define keys for your models in ember-orbit, declare them with the
This is equivalent to the following Orbit schema:
ember-orbit flattens all fields, including keys, to be directly accessible properties on the model, so you should be able to access this key via
Sorry to confuse, I'm only pointing out awkward areas with 0.16 that have been smoothed over for 0.17. I still use 0.16 myself in some projects and it's very stable in my experience, and is recommended as it's stable and has full docs. |
Thanks, adding I still don't have an answer to the question: how do I query by Things I have tried: // all of these seem to silently ignore everything but `type` and
// construct the URL `/prices` and return the whole set. Why
// does singular `findRecord` ever give me an array? I would hope
// that even if the server returns plural `data` it would be an error.
qb.findRecord({ type: 'price', id: remoteId });
qb.findRecord({ type: 'price', key: 'remoteId', value: remoteId });
qb.findRecord({ type: 'price', keys: { remoteId: remoteId } });
// this was just a guess and it throws
qb.findRecords('price').filter({ key: 'remoteId', value: remoteId })
// this constructs the URL /prices?filter[remoteId]=xxxx, which is not what we need
qb.findRecords('price').filter({ attribute: 'remoteId', value: remoteId }) |
In v0.16, you can query the store with the async findRecordByKey:
And you can query the cache with the sync peekRecordByKey:
I plan to deprecate these in v0.17 (but they'll still be available) in favor of the general purpose |
Thanks, I think that gives me the pieces I need to port this model to orbit. |
The orbit docs say:
From what I have discovered so far, option 1 is the default.
And I seem to be able to achieve option 2 by extending
JSONAPISerializer
with:But I have not been able to achieve option 3. It's distinct from option 2 because I need
myModel.id
to reflect the server's id. The use case is porting existing read-only models from ember-data, where the IDs are used in URLs that I would rather not break.My direct deps are @orbit/jsonapi 0.16.7 and ember-orbit 0.16.9.
The text was updated successfully, but these errors were encountered: