What is the correct way to name relations in Prisma? Are there guidelines or conventions I should follow? - prisma

I have a User model which can post Comments and vote on them. Comments can also be parented to each other (for nested comments like on HN or Reddit`).
model User {
[...]
// Comments the user has posted
comments Comment[] #relation("UserToComment")
// Comments the user has voted on
upvotedComments Comment[] #relation("_UpvoterToComment")
downvotedComments Comment[] #relation("_DownvoterToComment")
}
model Comment {
[...]
// Comment's author
author User #relation("UserToComment", fields: [authorId], references: [id])
authorId String
// Users who voted on the comment
upvoters User[] #relation("_UpvoterToComment")
downvoters User[] #relation("_DownvoterToComment")
// One-to-many self-relation for nested comments
parentId String?
parent Comment? #relation("Parent", fields: [parentId], references: [id])
children Comment[] #relation("Parent")
}
I have a few questions on how to correctly name these relations.
How should relation that describes the User being an author of several Comments be named:
"UserToComment"?
"Author"?
"CommentAuthor"?
"UserComments"?
I've read somewhere that many-to-many relation names are supposed to start with an underscore (but I'm not sure why, and whether this applies to one-to-many relations as well). How should the relation that describes the multiples Users being upvoters of multiple Comments be named:
"_UpvoterToComment"?
"UpvoterToComment"?
"UserUpvoted"?
"Upvoters"?
Finally, I have a Comment relating to itself for the nested comments. Should this relation be named:
"Parent"?
"Children"?
"ParentChildren"?
"CommentToComment"?
Any of the above but with the underscore in front?
Can you guys help me to understand the correct conventions here, give me some advice on how should name my relations?

General Advice on naming in prisma
Naming is a bit subjective. Normally, I think you should do what makes the most sense for you and your use-case. There are some conventions and rules that Prisma recommends, that you should follow as well:
Convention for model names
Convention for field names
However, there aren't any guidelines on naming relations.
Naming for the specific usecases mentioned
In general, go with whatever you think concisely describes the relationship itself. I can give you my personal opinion about the specific naming questions you brought up:
How should relation that describes the User being an author of several Comments be named:
I think UserComments make sense.
I've read somewhere that many-to-many relation names are supposed to start with an underscore.
This is something that Prisma does internally when automatically generating the underlying SQL. You don't have to worry about this at all, nor should you explicitly add a _ at the beginning of a name.
How should the relation that describes the multiples Users being upvoters of multiple Comments be named:
I would go with Upvoters.
Finally, I have a Comment relating to itself for the nested comments. Should this relation be named:
I would probably go with something like CommentResponses or CommentReplies.

Related

REST( GET method ) naming for getting a list of list of objects

I have a list of courses with a list of students. The idea is that a student can attend multiple courses.
The requirement is to return a unified list of courses-students where the "key" is like courseId + studentId. The GET result will be like:
courseId, courseName, studentId, studentName,...
My question is, which is the best approach to define this REST GET method. I have two solutions and any idea is welcome.
GET:api-name/v1/courses/students?version=5 - mening return from all courses the all students
GET:api-name/v1/courses-students?version=5 - in this case, is a dedicated method as courses-students
Any idea is welcome. Many thanks!
Update:
I was going to use solution 2.
Also, the remark that this relation could be considered a new resource is a strong argument.
I would bet on the second option, since you are exposing a new resource, which is the relationship between courses and students - even identifiable with that "key" relating the two IDs.
Going with this option may then allow you, for example, to find the new resource with the key, or filter this new resource with query string parameters (e.g. api-name/v1/courses-students?courseId=12,45&studentId=32,67), or request for students of an individual course (api-name/v1/courses/{courseId}/students), or for courses of an individual student (api-name/v1/students/{studentId}/courses).
There is a question with good answers on this topic here.

REST API URI for entities with two different keys

I must design an API to manage a Document entity: the originality of this entity is it can have two different ids:
id1 (number, i.e. 1234)
id2 (number, i.e. 89)
For each document, one and only one id is available (id1 or id2, not both)
Usually I solve this issue by using query parameters to perform some kind of "search" feature:
GET /documents?id1=1234
GET /documents?id2=89
But it works only if there is no sub-entity...
Let's say I want to get the authors of the documents :
GET /documents/1234/authors
Impossible because I can't know what type of id I get: is it id1 or id2 ?
GET /documents/authors?id1=1234
Not really REST I think because id1 then refers to the "Author" entity, not "Document" anymore...
GET /id1-documents/1234/authors
GET /id2-documents/1234/authors
Then you create two URIs that return the same entity (/author) not really REST compliant.
GET /documents/id1=1234/authors
GET /documents/id2=89/authors
It looks like a composite key created only for the API, it has no "backend" meaning. For me it sounds strange to create a "composite" key on the fly.
GET /document-authors?id1=1234
GET /document-authors?id2=89
In this case you completely lose the notion of tree... You end up with an API that contains only root entities.
Do you see another alternative ?
Which one looks the best ?
Thank you very much.
It seems to me that you're conflating two different resources here - documents and authors. A document has a relationship with an author, but they should be separate resources because the authors have existence from any individual document. With that in mind you need to ask whether your clients are searching for authors or documents. If it's authors, then they should be querying an authors API rather than a documents API.
e.g.For all the authors of documents with id1 89 or id1 1234 or id2 4444 you might query like this...
GET /authors?docId1=89&docId1=1234&docId2=4444
That should return a list of author representations. If people care about the documents themselves, the author representations could contain links to the documents.
Alternatively, if you're looking for documents then you should be querying that directly...
GET /documents?id1=89&id1=1234&id2=4444
What you're modelling as a sub-resource isn't really a subresource. It's a relationship between 2 independent resources and should be modelled as a set of links. Each document returned from the documents api should contain a set of authors links (if people really care about the authors) and vice versa from the authors to the documents.
Here's an opinionated solution from SlashDB, which allows for record filtering and traversing to related resources at the same time.
The example is similar to yours - two entities Artist and Album.
Let's identify the Artist first.
Artist by ID:
https://demo.slashdb.com/db/Chinook/Artist/ArtistId/2
Artist by Name:
https://demo.slashdb.com/db/Chinook/Artist/Name/Accept
An Artist may have issued Albums. The two entities are related. We allow extending the URL with the name of the related entity, like so:
https://demo.slashdb.com/db/Chinook/Artist/Name/Accept/Album
You can keep "going", say to get to the Tracks from those albums
https://demo.slashdb.com/db/Chinook/Artist/Name/Accept/Album/Track
And even continue filtering too i.e. only tracks, which are shorter than 300000 milliseconds:
https://demo.slashdb.com/db/Chinook/Artist/Name/Accept/Album/Track/Milliseconds/..300000

Parse.com one-to-one relationship Swift

A general parse.com relationship question really - using swift. I have a blogging app, for which there is a blog class, and a user class (along with a few others!) the blog class stores the associated user ID in a field for simplicity. Can I use includekey (or something similar) in a pfquery for the following;
firstly retrieve specific (or all) blog entries that match a criteria.
for each matching blog entry, check a field in the related user class for an option before returning the JSON list of entries
I suppose, sort of a subquery really, but wanted the whole thing to work in one pfquery if possible.
thanks!
Yes, you can do this with a relational query. The user stored in blog should be a pointer.
First create a query for the field in the user class, i.e.
userQuery.whereKey("age", greaterThan: 30)
(Do not execute this query)
Then, when adding constraints to your blog query, add
blogQuery.whereKey("user", matchesQuery: userQuery)

JPA ManyToMany relationship -- Why would association (join) table be empty

I have two entities Account and Position. The POSITION table and the ACCOUNT table have contents but the POSITION_ACCOUNT table, which I think should have at least one row, is empty. What could I be doing wrong? Here is the relevant code (I am using EclipseLink 2.4.2:
In Position:
#ManyToMany
private List accounts;
In Account:
#ManyToMany(mappedBy = "accounts",fetch=FetchType.EAGER,cascade=CascadeType.PERSIST)
#JoinTable(name="POSITION_ACCOUNT")
Confusing to me and perhaps relevant is that some examples I see annotate the getters and setters but others, as I am doing here, annotate the actual Lists.
It turns out that I needed to specify cascade=CascadeType.PERSIST on both sides of the relationship but there were other application-specific issues along the way. I don't know if reading the original question or this answer will be of much help to anyone. Sorry.

ORMLite foreign #DatabaseField with inverse mapping?

I'm implementing a small project and I'm wondering if ORMLite supports inverse mapping for #DatabaseMappings. What I am looking for is this similar to JPA's/Hibernates's inverse mapping. Following, hypothetical and rather silly example, a table BlogPost:
#DatabaseTable
public class BlogPost {
#DatabaseField(foreign = true)
private Author owner;
}
and the according Author class, not really that important:
#DatabaseTable public class Author { }
This results in the following SQL (just the relevant parts):
CREATE TABLE blogpost ( ... , owner_id INTEGER NOT NULL, ... )
CREATE TABLE author ( ... )
See how table blogpost now has a foreign key for author. However, I'd prefer it the other way around, i.e. author should have a blogpost_id foreign key. (I told you it was a silly example... ;).
With inverse mapping I could utilize cascades for deletes but I haven't found anything in the ORMlite docs about this. Is it not a feature or am I just missing something?
I'm a bit confused by the question but I thought I'd try to answer it anyway.
I don't understand how that would work #ilikeorangutans. I assume that there are multiple blogposts for a single author? So how could there be a single blogpost_id on the account channel? You could have a join table which contains an author_id and a blogpost_id but that just adds complexity.
If you take a look at this discussion and this webpage, you can see that Hibernate's inverse mapping is about who controls the relationship and is responsible for updating the rows. In both cases, BlogPost would have an author_id and not the other way around.
ORMLite does support the concept of "foreign collections" where you can add a BlogPost to the database by adding it to the collection in the Author object. For more information see the foreign collection documentation.
Sorry if I'm missing something.