if I think about it as a graph, it might be like: ...
# prisma-whats-new
z
if I think about it as a graph, it might be like:
Copy code
{
  allVideos {
   ...video
   watchedStatus(user: $user) {
      isWatched
   }
 }}
d
like so
okay let's tackle the matter
your current implementation is a Video-oriented one, and since this is a
User
case I would use what @panzupa said, and store the
Video
ID in a custom
User
field such as
watchedVideos
so, in your
User
schema you would have a
watchedVideos
field of type
[Video!]
with a
relationName
in between
so it would be something like:
Copy code
User {
 ID: ID!
 [....]
 watchedVideos: [Video!] @relationName(name:"UserWatchedVideos")
}
z
so when my frontend wants to show a list of "comedies", and have a viewed/not viewed indicator on each, how does it query
videos
?
d
that way, you could do a query such as
Copy code
query getUserWatchedVideos($user_id:ID!) {
  getUser(id:$user_id) {
   watchedVideos: {
     id
     url
     [....]
   }
 }
}
oh, that's a `filter`ing problem
p
not exactly
👀 1
d
now that we have the schema, and a query to retrieve all `watchedVideo`s you now implement a filter
p
because all relation have two end in GC
yes, as @Dukuo is say 🙂
d
Copy code
query getUserWatchedVideos($user_id:ID!) {
  getUser(id:$user_id) {
   watchedVideos(
                 filter: {
                       category_in: ["Comedy"]
                 }) {
     id
     url
     [....]
   }
 }
}
z
seems like that would only return videos that have been set as watched (or not)
d
(updated the query to reflect a
category
field)
I don't know how you are implementing your
category
field, but the example I typed is assuming you have a
category
field in your
Video
type with hardcoded category names
z
sure
d
but a more scalable solution would have a
Category
Type referenced within your
Video
Type
and then you would filter it same way I told above
t
the simple direct relation is one way of doing it. Depending on your needs in the future, you might also consider a new type, like Session/Watched that has a User and Movie field. By having a new type, you then know when the user watched it. Sometimes it can be nice to combine all such "user does something" in a generic Action type that has an enum or string with that type of action
☝️ 1
*with what type of action
d
did that answered your question @Zach Hobbs ?
z
@Dukuo with the solution you proposed, if User.watchedVideos[] was null (new user lets say), would your query still return all comedies?
d
not in theory, because it's filtering according to the records in
User.watchedVideos
but you are free to try and share the results 😁
t
on that note, a generic Action type makes it trivial to display logs of user actions and for example send out push notifications when they are created, and undoing an action is simply deleting the object.
z
@Dukuo right, that's going to be my challenge. I need to think about whether I can query videos and then if there is a User.watchedVideo[] value for that vid, include it
d
a generic
Action
type would be like a history for User's actions, right @trond? like if the user watches a video, you would store an
Action
with a
action
field equals to 'video', an ID of the
Video
and ID of a
User
, right ?
t
exactly
d
pretty interesting
that would abstract your actions
t
then if your app needs the ability to follow something, you simply make a follow action. Makes it easy to do feeds of content etc.
1
z
yeah, that could be nice
t
I'm still not sure what is best, to have a generic Action type or invent new types for each kind of action, they both have pros and cons, but I personally like the generic approach.
d
it depends of the scale I think
I'v had the same question in different scenarios and it all comes down to what the scale of your product is or is projected to be
t
yeah, probably a classic tipping point decision
d
a generic approach might work if the types have similar structure (cue-in `Interface`s)
won't work if they are too far apart in the graph
z
for data warehouses I've done generic actions, never done it for real-time backends/apis
t
yeah, an action log kind of ui is made easiest if it's a generic one, since then it's just one query
p
that's interesting subject, the performance of GraphCool
z
yeah, that's my big concern with going all in with GC vs building something, if I hit a performance wall will I be able to understand it/fix it
d
I believe is more of a design performance than GraphCool's, because its speed is very good in each case; if your userbase is small to medium size you shouldn't have any problems
further performance tweaks would be on a infrastructure level I guess
p
@Zach Hobbs since it's open source you're in better position now
z
yeah, def!
d
true that
t
and you can if you have to, by exporting data
scale = success = vc money paying for the exporting if really needed 🙂
p
@Dukuo I don't agree fully, maybe internal architecture of GraphCool "prefers" one solution over other
d
@trond I would think that is success = scale = vc money (and you can switch the last two in place depending of your product)
oh totally
z
for my original question, I considered just using a separate k/v store and basically looking up
watched
for each video in the response...basically decorating the graph.cool results
just because I don't know how the GC DB works internally for stuff like this
guess I just need to try it the GC way and see how it works
d
@panzupa what I meant is that is that this problems surface when you have enough users to watch the performance in a big scale scenario
as long as your
watched
field is in a User oriented way everything will be fine
because if you do it
Video
oriented you wouldn't be able to have a granular access to each user's preference
p
Having separate type
Action
can have security adavantage
I mean that updated / create on
Action
type is less serious than on
User
type, however in GC permission queries are quite fine grained (single field level)
d
yup, it really boils down to design preferences
p
so it's maybe not an advantage...
d
I'm more on the
Action
type as well
p
just for conversation sake, what fields would you put in that
Action
type?
user ID!
and `interface ID! - does GC supports interfaces? I haven't used them if it does...
d
a bare bones implementation would have an
action
field which could be with a value of `video`for this example, a
Video
ID and a
User
ID
not yet
but that would be the solution for all this subthread
Interfaces are awesome
and pretty useful once you get the grip of it
p
so, without interfaces we whould have to create new Action type for each other action, right?
Do I understand you correctly?
t
right so going with a generic Action type, one could argue that a downside is that the type would be cluttered with many ID fields for each type that the action needs to refer to, for example "toUser" if the a follow action should let a user follow another user.
d
more like several `fieldID`s in your
Action
type
right now i'm facing a similar issue with security groups
you would need a
field
for each
Type
you would want in an
AccessGroup
that would be much easier and scalable with interfaces
p
I get it. Thanks for clarification
d
btw since we are talking about interfaces, is there any roadmap for that @nilan?