graphqlapollo-serverprisma-graphqlnexus-js

Resolve relationships in graphql using nexus


I'm new to using nexus and graphql but I'm having a hard time getting the following to work:

I am using:

    "@prisma/client": "^5.4.1",
    "apollo-server": "^3.12.1",
    "graphql": "^16.8.1",
    "nexus": "^1.3.0",
    "python": "^0.0.4"

And this is running in a node container (node:20-alpine3.17)

My data model:

enter image description here

I defined the types and some query definitions using the nexus syntax.

User:

export const User = objectType({
  name: 'User',
  definition(t) {
    t.int('id')
    t.string('name')
    t.string('email')
    t.list.field('posts', {
      type: 'Post',
      resolve: async (User) => {
        if (User.id) {          
          await getPosts(User.id)?.then((result) => {
            return result
          })
        }
        return null
      }
    })
  }
})

Where getPosts:

export function getPosts(id: number | null) {
  if (id) {
    return db.post.findMany({where: {id: id}})   
  }
  return null
}

Post:

export const Post = objectType({
  name: 'Post',
  definition(t) {
    t.int('id')
    t.string('title')
    t.string('body')
    t.boolean('published')
    t.field('user', {
      type: 'User',
      resolve: (o) => {
        return o || null
      }
    })
  }
})

Query:

export const PostQuery = extendType({
  type: 'Query',
  definition(t) {
      t.field('posts', {
        type: nonNull(list('Post')),
        resolve(_root, args, ctx) {
          return ctx.db.post.findMany({ where: { published: true } })
        }
      }),
      t.field('users', {
        type: list('User'),
        resolve(_root, args, ctx) {
          return ctx.db.user.findMany()
        }
      }),
      t.field('user', {
        type: 'User',
        args: {
          id: nonNull(intArg())
        },
        resolve(_root, args, ctx) {
          return ctx.db.user.findUniqueOrThrow({ where: { id: args.id } })
        }
      })
  }
})

And finally the nexus generated graphql schema:

type Post {
  body: String
  id: Int
  published: Boolean
  title: String
  user: User
}

type Query {
  posts: [Post]!
  user(id: Int!): User
  users: [User]
}

type User {
  email: String
  id: Int
  name: String
  posts: [Post]
}

Most of this works, except resolving the relationships (posts on User and user on Post)

enter image description here

enter image description here

Am I going about it the wrong way to resolve these relationships? I looked at the nexus example code but couldn't find a good example.

Thanks!


Solution

    1. You're searching posts by id where you should be searching by userId. Change your getPosts function to:
    export function getPosts(userId: number) {
        return db.post.findMany({where: {userId}})   
    }
    
    1. You're not searching for users correctly in your Post type - your parent object will be a database record from the Post table and will include userId as key. A single record needs to be found, not many.
    t.field('user', {
      type: 'User',
      resolve: ({ userId }, _, ctx) =>  ctx.db.user.findOne({where: {id: userId}})
    })