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

Prisma JS/TS client generator exclude attribute #7380

Closed
dpetrick opened this issue May 31, 2021 · 18 comments
Closed

Prisma JS/TS client generator exclude attribute #7380

dpetrick opened this issue May 31, 2021 · 18 comments
Labels
domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. domain/psl Issue in the "PSL" domain: Prisma Schema Language kind/improvement An improvement to existing feature and code. topic: exclude topic: schema

Comments

@dpetrick
Copy link
Contributor

dpetrick commented May 31, 2021

Currently, the client selects all fields when querying a model. There's no easy way to exclude a field by default. This makes it easy to accidentally send sensitive information back to the client, for example a password hash on a user model.

It is infeasible or too complicated to build a solution for this issue without undermining the current design of the client (exclude can't neatly fit in besides include and select in the type system) or building complex hacks that do not work for more involved scenarios.

This proposal introduces a generator attribute that will instruct the client to not query a field by default, but it must be explicitly selected instead for it to get fetched.

Prisma Schema Language (PSL) Syntax Proposal

With the concept of generator attributes being a decided addition in the future of the Prisma Schema (#7209), we can already decide to implement exclude as a "known" generator attribute, meaning that while we don't have pluggable generators formalized, we can skip the generic plugin part and include it first-party into the Prisma code until we have a real system in place:

generator client { ... }

model Model {
    ...
    field String @client.exclude
}

The exclude property is namespaced to the generator that will use it in the end.

Technical Details

The attribute will be attached to all places in the underlying protocol (currently internal, used by the language generators) where something has been derived from the field:

{
    "name": "Model",
    "fields": [
        {
            "name": "field",
            "args": [],
            "isNullable": false,
            "attributes": [{
                "generator": "client",
                "name": "exclude"
            }],
            "outputType": {
                "type": "String",
                "location": "scalar",
                "isList": false
            }
        }
    ]
}

Note that the above is not a final version and may change.

Feedback

  • Do you agree with the exclude naming? If not, what would be a preferable alternative?
@dpetrick dpetrick added kind/feedback Issue for gathering feedback. kind/improvement An improvement to existing feature and code. topic: schema labels May 31, 2021
@janpio janpio added topic: exclude topic: psl-wg domain/psl Issue in the "PSL" domain: Prisma Schema Language and removed topic: psl-wg labels May 31, 2021
@un33k
Copy link

un33k commented Jun 8, 2021

In the above context and with the suggested implementation at schema level, exclude may not be as self-explanatory as explicit.

How about this alternative ?

generator client { ... }

model Model {
    ...
    password String @client.explicit // client must explicitly request this field
}

However, if we want to use something at the query level, exclude would be great, but it will collide with include that is used for relationship inclusion.

@flybayer
Copy link

flybayer commented Jun 8, 2021

In English, "explicit" usually has the connotation that something is for adults. So not sure that's the best here.

I vote for excludeByDefault

model Model {
    field String @client.excludeByDefault
}

@un33k
Copy link

un33k commented Jun 8, 2021

@flybayer "I explicitly asked Tom not to buy bitcoin today" - What part of it is pointing to adult ? Everything is context based, and we are in programming and ORM realm, and not talking about watching movies etc. ;)

excludeByDefault works as well.

@elmaxe
Copy link

elmaxe commented Jun 8, 2021

I suggest @hidden, but excludeByDefault also works.

model User {
  password String @hidden
}

@joslarson
Copy link

How about @withhold or @client.withhold, meaning to suppress or hold back.

model User {
  password String @withhold
  sourceData Json @withhold
}

I like that it suggests the field is available (something exclude/private/hidden doesn't convey IMO) without implying that the data is sensitive (you might want to exclude a field by default just because it's heavy or not often used)

@AnandChowdhary
Copy link

We can also try @public and @private, and maybe even an option to mark everything as private by default:

generator client {
  provider = "prisma-client-js"
  defaultVisibility = "public"
}

model User {
  name     String  @public // Optional because @public is the default
  password String? @private
}

@tavindev
Copy link

IMO, private would work best. Like, if you think about the client and the server as Classes (OOP), it suggests that @private fields would be only accessible to the server and, thus, not returned to the client. I'm really looking forward to this feature, it'll be very helpful.

@un33k
Copy link

un33k commented Jun 28, 2021

Folks, please understand that Prisma is an ORM, and it has no business of, or should have awareness of what should stay on the server and what should go on to the clients. You query, and ask Prisma to withhold some fields.

I am hoping for that feature ...

@jasonkuhrt
Copy link
Member

jasonkuhrt commented Jun 29, 2021

"explicit" is interesting. Not sure I agree about the adult connotation, might say more about the reader's state of mind than anything 🤔.

Another I've thought of before is @client.selectByDefault(false) where the default is simply true for all scalar fields.

private/public are very generic and loaded words. I think these could age badly as more features land (thinking maybe authz stuff).

If we start with explicit terms we can always bring in more generic/sugar ones later in a backwards compatible way.

The reverse is not true if we start with bold general nice but risky terms.

@MahmoudThePeltist
Copy link

Has the terminology question been settled yet? while I personally prefer @client.hidden or @client.exclude, I'm honestly fine with bleep_bloop if the functionality is added 😅,

@Dilven
Copy link

Dilven commented Oct 25, 2021

any updates?

@janpio janpio added the domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. label Nov 5, 2021
@massivefermion
Copy link

massivefermion commented Nov 29, 2021

Folks, please understand that Prisma is an ORM, and it has no business of, or should have awareness of what should stay on the server and what should go on to the clients. You query, and ask Prisma to withhold some fields.

I am hoping for that feature ...

I agree, this has nothing to do with the models. But we should be able to exclude fields in queries. +1 for this feature!

@albandum
Copy link

Looks like the discussions have been going on around this feature for almost 2 years, greatly needed on our side as well :)
And thanks for the work guys, Prisma is great, even without this ;)

@arthurguedes375
Copy link

feature

I think that even though prisma should not care whether the information is private or not we still need an ease and clean way to just say that some fields should not be selected unless we actually tell them to, and imagine a table that a good part of the data is not returned to the user, then we would have to manually remove each one of them every time we want to query that table, i think that so far adding the @client.selectByDefault(false) is the nicest and cleanest way not to select some fields

@IdanYekutiel
Copy link

Totally agree, would love to see this implemented sometime soon!

@ravibisht
Copy link

We can also consider @expose(false) by default, @expose(true). The Idea is the server can use the @expose(false) but while object deserialization to JSON or Other Format. It excludes itself.

@ivangabriele
Copy link

A default boolean var set to true is not a good and intuitive practice. It's better to use an antonym in order to have the default value set to false.

@janpio janpio removed the kind/feedback Issue for gathering feedback. label May 31, 2022
@janpio janpio changed the title Prisma JS/TS client generator exclude attribute Prisma JS/TS client generator exclude attribute Jun 20, 2023
@janpio
Copy link
Member

janpio commented Jun 10, 2024

We have decided not to go with @exclude or similar via PSL for now, more information soon in #7380

@janpio janpio closed this as not planned Won't fix, can't repro, duplicate, stale Jun 10, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
domain/client Issue in the "Client" domain: Prisma Client, Prisma Studio etc. domain/psl Issue in the "PSL" domain: Prisma Schema Language kind/improvement An improvement to existing feature and code. topic: exclude topic: schema
Projects
None yet
Development

No branches or pull requests