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

[Feature Request] Model-Level CRUD Hooks #1128

Open
andrewpeters9 opened this issue Mar 11, 2024 · 0 comments
Open

[Feature Request] Model-Level CRUD Hooks #1128

andrewpeters9 opened this issue Mar 11, 2024 · 0 comments

Comments

@andrewpeters9
Copy link

andrewpeters9 commented Mar 11, 2024

Is your feature request related to a problem? Please describe.

  • Prisma's current API for hooks (esp. at model level) is lacking.
    • .$extends requires explicit method wrapping, and doesn't support method-level extending.
    • Computed fields (which can cover some use-cases of READ hooks) are methods, and therefore unserializable - meaning, they're unable to be passed to the frontend unless explicitly called in the server
  • Prisma Pulse is the current best solution, but is a separate third-party service (which currently only supports Postgres) and therefore may not be a practical solution for most.
  • Zenstack's philosophy seems to jibe with locking down actions/logic to the model level, and therefore, thinking about implementing model-level CRUD hooks in the future may be appropriate

Example Usecases:

  • Create: Famous Instagram-DB use-case of implementing a counter on a model-level field for # of likes as the db history of individual like objects is too big to cache. I.e., creation of Like document would fire a hook that updates their Post document.
  • Read: Some high-security apps need to keep read logs for everything an employee has accessed.
  • Update: After updating User model with a membership level, you may want to send the user an email thanking them for purchasing xyz subscription
  • Delete: cleaning up other model rows that may not be able to directly link to the deleted record for whatever reason

Describe the solution you'd like

  • Definable-hooks applied at the enhance call, i.e. allowing the user to execute JS based on
  • Hooks will be fired even if I update a model via a call from a model above/below:
user.update({
   data: {
      subscription: {
          create: {
              // etc ... 
          }
      }
   }
})
  • Post-MVP: Hooks would be able to access the prev/post document (or maybe you could have preX, postX hooks? - Post-Post-MVP may allow for pre hooks to cancel an action (pie-in-the-sky, I know ...))
  • Post-MVP: provider the hook's function params access to the user that made the CRUD request. Useful for implementing read-logs etc.

Potential Challenges:

  • AFAIK, there isn't an inbuilt API that wraps the Prisma core methods
  • Determining when a model is CRUD'ed via a parent/children call may be tricky too

Comment from @ymc9

This is some thought background about access conrol. As for CRUD hooks, I fully agree with you that implementing with Prisma client extensions can be quite challenging given the flexibility of nesting - it's very easy to have a leaky implementation. I think it's a good idea that we "reimplement" some kind of hook at the TS-API land, like allowing you to provide simple callbacks when calling enhance (model + operation + action), and the API internally deals with traversing nesting, and probably also guarantees a transaction boundary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant