Replies: 9 comments
-
|
Beta Was this translation helpful? Give feedback.
-
I definitely see a challenge here for bigger apps. I also definitely think re-frame should facilitate an approach; a best practices document would help re-frame users a lot. If these best practices need non-trivial code, the code could be in re-frame or in an external library. |
Beta Was this translation helpful? Give feedback.
-
I had this discussed with a friend while engaging in a We/he ended working on a custom language/middleware that was able to denormalize the data in the backend given data relations and send it to the frontend shaped right. While investigating this, I though about the ol' good datalog for defining relations on data and then perform the queries on a map. The immense @fogus even revived it and made it cljs compatilble in bacwn so it would theoretically be possible to apply this to the |
Beta Was this translation helpful? Give feedback.
-
It is difficult for me to comment in any depth on this. Because of the kinds of apps we write, I don't struggle (yet) with this problem. So I have no opinions distilled from hand to hand combat. It does seem like this should start as a library, or maybe just a tutorial enumerating options and techniques. I'd be happy to see these tutorials end up in the developing If you are keeping normalised data around, then it is just a matter of time before you'll need to join with I do have a further cautious observation: at core, it seems as if the goal is to turn If so, we should acknowledge that this can be achieved via the disciplined application of certain techniques and conventions OR ... ... I wonder if the goal should be bring DataScript into re-frame more directly. With the adjustments in 0.8.0 that should now be easier to do (claim untested). Imagine a world in which event handlers are given Like I say, the pieces are all there to make this happen pretty easily (claim untested). |
Beta Was this translation helpful? Give feedback.
-
There was good enthusiasm on this initially. I can't work on this, myself, but I'd like to encourage someone else to take this forward. Leaving open for the moment, but will close if no further progress. |
Beta Was this translation helpful? Give feedback.
-
In the absence of further activity or input, and in the interests of tiding up ahead of v0.9,, I'm going to close this issue. I reiterate my earlier assessment:
I believe the real job here is for someone to document techniques and best practice around representing relational data in a map. But that someone isn't going to be me (I don't have that itch). |
Beta Was this translation helpful? Give feedback.
-
If you're interested in this issue you might want to check out our pre-release of SubGraph. It handles normalization transparently for the user and uses datomic or om.next style pull queries to retrieve subscription graphs. Still alpha quality and more documentation is needed but we've been using it in production for months. |
Beta Was this translation helpful? Give feedback.
-
There is also this |
Beta Was this translation helpful? Give feedback.
-
Libraries are listed in an FAQ: If there are any additions can you supply a PR updating that FAQ document please. |
Beta Was this translation helpful? Give feedback.
-
This issue is mostly an invitation to continue the Slack discussion.
The problem
I frequently find myself writing normalization/denormalization code in various places. It would be nice to have an "officially blessed" (or documented) approach, be it a part of re-frame, a library or just a documented pattern.
What's normalization?
The long explanation can be found in Om.Next wiki. In short, in this particular context, it's a practice of storing "objects" (or entity's properties if you may) in an (often) top-level map by their ID. For example, if we have some
Snippet
s belonging to a bunch ofUser
s, we may structure app DB as follows:There are two separate concerns resolved by normalization: ordering and modification consistency.
Modification consistency
I'll lift an example from Om.Next docs. Let's say you have the following structure:
You see that "Mary" occurs in both lists? If you want to increment Mary's points, you'll need to ensure that you are incrementing them in both places. On the other hand, if you normalize the structure like this
you can increment the value only once while ensuring consistent data across your app. Please note that Om.Next uses explicit "reference typing" like
[:person/by-name "Mary"]
, while in others examples in this issue I use "implicit" one with int IDs. Which one do you think is better?Ordering
Sometimes you want to preserve a server-provided ordering (let's say you receive a vector of
Snippet
s) while having a way to access "objects" by IDs. You have at least three alternatives:Snippet
s, hopefully exploiting pointer sharing. Now you need to manually ensure modification consistency between both structures.map-indexed
to add an index into eachSnippet
and use eithersorted-map-by
or sort by that index in your views. It's workable but honestly doesn't feel right.Snippet
s in a map, use a vector of IDs to preserve order.Questions
Beta Was this translation helpful? Give feedback.
All reactions