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

Allow custom field attributes #3102

Open
timsuchanek opened this issue Jul 22, 2020 · 25 comments
Open

Allow custom field attributes #3102

timsuchanek opened this issue Jul 22, 2020 · 25 comments

Comments

@timsuchanek
Copy link
Contributor

Let's say I want to make sure, that an email is always valid before it gets created.
It would be awesome, if I could add an @email directive like so:

model User {
  id    Int @id
  email String @unique @email
}

While it makes sense, that @email is not allowed right now, if we would allow it, users could now add an email validation middleware.
Allowing top-level @email probably doesn't make sense though to keep validation rather strict so that we can also help with typos.

However, the same as in HTTP Headers, which can start with X- or HTML attributes, which can start with data-, we could add a namespace for custom directives, for example @custom.X.

That would allow a whole world of extensions for Prisma, which can be dealt with through middlewares.

And of course, this is just a wild idea, it could also just be trash and maybe we shouldn't do it.
So let's have a discussion if this even makes sense :)

@timsuchanek timsuchanek added the kind/feedback Issue for gathering feedback. label Jul 22, 2020
@matthewmueller
Copy link
Contributor

matthewmueller commented Jul 23, 2020

I'm +1 for the idea. I've seen this request multiple times.

As you mentioned with X-, the only thing we'd need to be cautious about is forward compatibility. We don't want to break people's schemas by introducing an official prisma attribute that clobbers their existing custom attribute.

Some other ideas:

  • @data-email
  • @x.email
  • @x-email
  • @meta.email
  • +email

The possibilities for tooling also increase if we make our Prisma schema parser more accessible (or officialize & open source the JS version).

@pantharshit00
Copy link
Contributor

Another idea:
@custom(email)

@Errorname
Copy link
Contributor

Errorname commented Aug 14, 2020

Another idea:
@custom(email)

I would favor a syntax without parentheses to allow arguments on the custom directives: @custom.something("arg1", 2) instead of @custom(something("arg1", 2))

But on the other hand, it would match what is already used for @default(cuid()) 🤔

@SrZorro
Copy link

SrZorro commented Nov 24, 2020

NOTE: This comment is deprecated as we are no longer working on this implementation

Your request looks looks like a proposal we have at my company, we released an RFC for a downstream library that uses Prisma to generate a CRUD system and we are building on top of it a system to add attributes like the ones you want (validation and authorization mainly, but more plugins could be created).

The library is typegraphql-prisma, so the current implementation of this extension system is typegraphql-prisma generator specific but if you want to check it out, we wanted to structure it in a way so is as compatible as posible with Prisma.

I was hopping that if this proposal has some traction for that library it could be wrought back upstream to Prisma as a real world example of how this system could work, but for now it was easier to implement it with only one specific generator that trying to implement it at Prisma level.

You can find the RFC in this issue, any feedback is welcome to improve the proposal, we are currently implementing it already but we would like to get feedback from the community.

@pantharshit00 pantharshit00 added kind/feature A request for a new feature. team/client Issue for team Client. and removed kind/feedback Issue for gathering feedback. labels Jan 13, 2021
@stevefan1999-personal
Copy link

stevefan1999-personal commented Feb 18, 2021

I came across this for MichalLytek/typegraphql-prisma#35 and MichalLytek/typegraphql-prisma#43

Yes, I do agree adding a custom attribute for my kind of usage looks a lot more ergonomic and natural rather than hacking with the AST comment node, and I see that it's not that possible right now I guess😆why don't we just say reserved attributes for all the pre-existing attributes and otherwise to be custom attributes just like golang😂

Referenced from gorm docs:

type Cat struct {
  ID    int
  Name  string
  Toy   Toy `gorm:"polymorphic:Owner;"` // you see the custom attributes here? maybe we can just use @ instead
}

type Dog struct {
  ID   int
  Name string
  Toy  Toy `gorm:"polymorphic:Owner;"`
}

type Toy struct {
  ID        int
  Name      string
  OwnerID   int
  OwnerType string
}

@Mark-Panda
Copy link

I want to get custom instructions like GraphQL to identify instructions in prisma to generate logic code。
Is there any hope?

@unlight
Copy link

unlight commented Apr 15, 2021

@timsuchanek
Please, tell us what is the status of this feature request? Is there a internal discussion about it? Is it planned for far future, near or nearest...

@R9295
Copy link

R9295 commented May 11, 2021

+1

@ajmnz
Copy link

ajmnz commented Jul 20, 2021

Moving ideas in #8357 to this thread


For example, it would be really nice if we could do something like the following directly in our models

model User {
  id    Int    @id @default(autoincrement())
  name  String
  email String @unique @isEmail // <--
  Bio   Bio
}

model Bio {
  id      Int     @id @default(autoincrement())
  content String?
  url     String  @isUrl // <--
}

Or even custom regex validation

model ShippingAddress {
  id      Int    @id @default(autoincrement())
  name    String
  zipCode Int    @isRegex(/^\d{5}(?:[- ]?\d{4})?$/)
}

As a side note, think the possibilities this would open for autocompletion if this proposal goes forward and gets implemented into TypeScript.

@JuanM04
Copy link

JuanM04 commented Jul 26, 2021

If only Regex is supported, it would be a huge improvement. Nonetheless, I would be nice to have more operations, like @greaterThan, "required if COLUMN is equal to VALUE", etc.

@Mark-Panda
Copy link

When is it expected to be achieved

@brooksvb
Copy link

Any movement on this issue? Despite how much I enjoy Prisma so far, I'm about ready to move to a different ORM because of this limitation.

@nikolasburk nikolasburk changed the title Allow custom field directives Allow custom field attributes Jul 7, 2022
@abenhamdine
Copy link

abenhamdine commented Aug 24, 2022

@prisma team : please don't do that.

It will lead inexorably you to reimplement all the validation stuff made by many many libraries in the wild (joi, zod, superstruct, json schema...).
Joi has been developped since more than 5 years : do you really want to reimplement it ?
Prisma should be focused on controlling/querying the db, not validating input data.

Prisma already makes types based on its models accessable, there are libraries that can build validations based on those types like class-validator or typescript-ts.

Instead, do that : #3388
Because it's a main feature of db schema, and since Prisma is in charge of creating/migrating the schema, it should allow us to express SQL check rules.

@johnkm516
Copy link

johnkm516 commented Sep 19, 2022

@abenhamdine
I don't think anyone here is asking @prisma to reimplement joi and support every possible object type validation.
All we need is the ability to extend the Prisma schema with custom attributes, access it in the DMMF, and if needed, implement the validation ourselves. ORMs traditionally did not have its own schema declaration file like Prisma does, it extended an object model which meant objects could have any other custom annotations / directives / attributes separate from the database validations. Allowing custom attributes allow users to create extensions, such as supporting regex as an attribute, or graphql directives and the relevant validations ourselves.

The reason why people want this is because Prisma schemas are becoming a single source of truth for data models (as it should be), which means code generation has to rely on Prisma schemas.

@jmarbutt
Copy link

jmarbutt commented Oct 7, 2022

I would also like the ability to have custom attributes that I can parse out from the Prisma.dmmf.datamodel, I want to use it for some very basic attributes on how to display these items in the UI.

For example

model Contact {
   id   String @default(dbgenerated("gen_random_uuid()")) @db.Uuid
   firstName String @textbox('First Name') @showongrid
   lastName String @textbox('Last Name') @showongrid
   isActive Boolean @checkbox
   isNew Boolean @radiobox
   lastActivity DateTime @datebox @readonly
}

@0xTK421
Copy link

0xTK421 commented Nov 1, 2022

I am also interested in this topic, it makes sense to keep application-specific attributes close to the model definition.

I like either

- @customValue
- @custom('value')

to appear in the dmmf.

@janpio
Copy link
Member

janpio commented Nov 2, 2022

2 comments with additional use cases or comments in another, now closed issue:
#1660 (comment)
#1660 (comment)

@chrisui
Copy link

chrisui commented Jan 25, 2023

Another use-case that isn't just "extended validation" and is actually more ideally implemented at sql/query level: immutable rows and fields. Only current way to do this is client extensions or middleware but really we want to enforce this at a schema and db level.

Eg.

model Event {
  id      String @id
  type    String
  payload Json

  @@immutable
}

@janpio
Copy link
Member

janpio commented Jan 25, 2023

@@immutable in your example would not actually be a "field attribute", but a "block/model attribute". That might be worth its own feature request with a description of your use case @chrisui as that sits on a different level for us.

@jiashengguo
Copy link
Contributor

jiashengguo commented Feb 10, 2023

Is it possible to have this feature supported in the near future? 😅

As an alternative, you may want to take a look at a Prisma extension library ZenStack that we are currently working on. The schema is fully compatible with Prisma Schema, and you can have syntactic custom attributes as below:

model User {
    id        String @id
    email     String @email
    password  String @password @omit
    // everyone can signup, and user profile is also publicly readable
    @@allow('create,read', true)
}

attribute @email()

attribute @password(saltLength: Int?, salt: String?)

attribute @omit()

attribute @@allow(_ operation: String, _ condition: Boolean)

Moreover, It would still work with all the existing generators of Prisma using /// comment: solution. If you're interested, I have also written a post about the implementation details, which you may find helpful.

@jdkdev
Copy link

jdkdev commented Feb 26, 2023

To keep the party going, I'll add that I also have a hand-rolled generator to achieve want I wanted with attributes:
image

I would like to see something standard for custom attributes as well.

Thanks!

@djuleAyo
Copy link

AY is it just me or custom attributes can be used for far more that validation?

IE authorization, ui controls, and all other kinds of things allowing powerfull code generation and control of logic?

model User {
  id   Int     @id @default(autoincrement())  @public
  name String?  @formCollected @public

  email    String @unique  @self  @admin @friends  @formCollected
  password String  @never  @etc etc

  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  trackers Tracker[]
  crons    Cron[]

  firstDayOfWeek FirstDayOfWeek @default(Monday)
  darkMode       Boolean @default(true)
  alowCron       Boolean @default(false)
}

@luxaritas
Copy link
Contributor

Having custom attributes accessible via DMMF as a way to define information that could be used to auto-generate an admin interface (while being co-located with the actual fields) would be really handy

@jmarbutt
Copy link

Has there been any progress on this? It would be amazing

@janpio
Copy link
Member

janpio commented Aug 31, 2023

Related: #4002

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

No branches or pull requests