Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Nexus ignores Prisma middleware #1130

Open
habovh opened this issue Nov 19, 2024 · 0 comments
Open

Nexus ignores Prisma middleware #1130

habovh opened this issue Nov 19, 2024 · 0 comments
Labels
type/bug Something is not working the way it should

Comments

@habovh
Copy link

habovh commented Nov 19, 2024

Description

I am using olivierwilkinson/prisma-soft-delete-middleware to keep important models in the DB even after they are deleted. However, when used in conjunction with Nexus the middleware is ignored, which leads to runtime errors due to inconsistencies withe the gql schema.

Repro Steps/Link

db.ts:

export const db = new PrismaClient()

db.$use(
  createSoftDeleteMiddleware({
    models: {
      Category: true,
    },
    defaultConfig: {
      field: 'deletedAt',
      createValue: (deleted) => {
        if (deleted) return new Date()
        return null
      },
    },
  }),
)

schema.prisma:

model Post {
  categoryId String?
  category   Category? @relation
}

model Category {
  deletedAt DateTime?
  createdBy User
  name String
}

Post.ts:

import {
  Post as PrismaPost,
} from 'nexus-prisma'

const Post = objectType({
  name: PrismaPost.$name,
  definition(t) {
    t.field(PrismaPost.category)
  },
})

Category.ts:

import {
  Category as Prisma Category,
} from 'nexus-prisma'

const Category = objectType({
  name: PrismaCategory.$name,
  definition(t) {
    t.field(PrismaCategory.createdBy)
  },
})

When querying a Post with a soft-deleted category, the category will be returned. This in itself would not cause issues other than the data being accessible when it shouldn't.

query post {
  post(id: 1) {
    category {
      name
    }
  }
}

However, errors can arise when querying non-scalar fields:

query post {
  post(id: 1) {
    category {
      name
      createdBy {
        firstname
      }
    }
  }
}

For some reason the nested access to the Category.createdBy field will return null because of the Category soft delete, but the category itself will not be null. In this specific case, this triggers a GraphQL error because my schema sets the createdBy as a non-null field on the Category type.

I'm not sure what's causing this partial support, but it's giving me headaches.

Current workaround is to implement a custom resolver in the object type declaration that defines a field that points to a soft-deletable record.

For example:

const Post = objectType({
  name: PrismaPost.$name,
  definition(t) {
    t.field(PrismaPost.category.name, {
      ...PrismaPost.category,
      resolve(root, args, ctx) {
        if (!root.categoryId) return null
        // Explicit use of `findUnique` will get handled by the middleware.
        return ctx.db.category.findUnique({ where: { id: root.categoryId } })
      },
    })
  },
})

Any insights would be appreciated here!

@habovh habovh added the type/bug Something is not working the way it should label Nov 19, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type/bug Something is not working the way it should
Projects
None yet
Development

No branches or pull requests

1 participant