I have a problem, thx for any help.
With prisma we can use include with where conditions for models with a relation. If I make include conditions I get the right result. If I return it to the frontend it gets overwritten. I want to return exact my result from the backend.
I have at the frontend a query (ApolloClient, gql) like. It will return an array of comments for each post, I just want to have the first Comment for each post.
const POSTS = gql`
query posts {
posts(postId: $postId) {
id
comments{ // at the backend I have conditions for the comments
id
}
}
}
`;
Backend: Primsa and graphql nexus
Prisma Schema
model Post {
id String @id @default(cuid())
comments Comment[]
}
model Comment {
id String @id @default(cuid())
post Post @relation(fields: [postId], references: [id])
postId String
}
Nexus Model
const Post = objectType({
name: 'Post',
definition(t) {
t.model.id()
t.model.comments()
})
const Comment = objectType({
name: 'Comment',
definition(t) {
t.model.id()
t.model.post()
t.model.postId()
})
Resolver
export const posts = queryField('posts', {
type: 'Post',
list: true,
args: {
...
},
resolve: async (_parent, args: any, { prisma, request }, info) => {
const posts = await prisma.post.findMany({
include: {
comments: {
take: 1
}
}
})
console.log(posts)
//Perfect result I want to return the include condition. But at the frontend I have all
//comments
return posts
},
})
The console.log(posts) is exact what I want to return!. Every post has an Array of ONE Comment. I return the posts and at the frontend every post has an Array of ALL Comments, what I don't want. How can I prevent that the frontend query overwrite the backend return? The fields are the same.
I can't add a comment, so I am adding this to another answer.
Like I said with my PrismaSelect
plugin, you can't use nexus-plugin-prisma
t.model
, t.crud
. You will need to use Pal.Js CLI to autoGenerate all CRUD and ObjectTypes for all models.
const Post = objectType({
name: 'Post',
definition(t) {
t.model.id()
t.model.comments() // this field will overwritten by next one so this not needed
t.list.field('comments', {
type: 'Comment',
list: true,
resolve: (parent, args, { prisma }) => {
// here parent type include all other fields but not this field
return prisma.comment.findMany({ // this query is very wrong will case N+1 issue
where: {
postId: parent.id,
},
take: 1,
})
},
})
})
Example
model User {
id Int @default(autoincrement()) @id
createdAt DateTime @default(now())
email String @unique
name String?
password String
posts Post[]
comments Comment[]
}
model Post {
id Int @default(autoincrement()) @id
published Boolean @default(false)
title String
author User? @relation(fields: [authorId], references: [id])
authorId Int?
comments Comment[]
}
model Comment {
id Int @default(autoincrement()) @id
contain String
post Post @relation(fields: [postId], references: [id])
postId Int
author User? @relation(fields: [authorId], references: [id])
authorId Int?
}
Here is my Pal.Js CLI generated type for Post model
import { objectType } from '@nexus/schema'
export const Post = objectType({
name: 'Post',
definition(t) {
t.int('id', { nullable: false })
t.boolean('published', { nullable: false })
t.string('title', { nullable: false })
t.field('author', {
nullable: true,
type: 'User',
resolve(parent: any) {
return parent['author']
},
})
t.int('authorId', { nullable: true })
t.field('comments', {
nullable: false,
list: [true],
type: 'Comment',
args: {
where: 'CommentWhereInput',
orderBy: 'CommentOrderByInput',
cursor: 'CommentWhereUniqueInput',
take: 'Int',
skip: 'Int',
distinct: 'CommentDistinctFieldEnum',
},
resolve(parent: any) {
return parent['comments']
},
})
},
})
when you use my Pal.js CLI, your frontend request will be like this
query {
findOnePost(where: {id: 1}) {
comments(where: {}, take: 1){
id
}
}
}
``