Nexus-plugin-prisma: Unprojected relations should not appear in GQL schema

Created on 11 Oct 2019  路  2Comments  路  Source: graphql-nexus/nexus-plugin-prisma

model User {
  id    Int    @id @unique
  email String @unique
  posts Post[]
}

model Post {
  id     Int    @id
  author User[]
}

```ts
const Mutation = mutationType({
definition(t) {
t.crud.createOneUser()
},
})

const User = objectType({
name: 'User',
definition(t) {
t.model.id()
t.model.email()
},
})

```graphql
type Mutation {
  createOneUser(data: UserCreateInput!): User!
}

input PostCreateManyWithoutPostsInput {
  connect: [PostWhereUniqueInput!]
  create: [PostCreateWithoutAuthorInput!]
}

input PostCreateWithoutAuthorInput

input PostWhereUniqueInput {
  id: Int
}

type User {
  email: String!
  id: Int!
}

input UserCreateInput {
  email: String!
  posts: PostCreateManyWithoutPostsInput
}

In the above

  • posts field in UserCreateInput should not exist
  • PostCreateManyWithoutPostsInput should not exist
  • PostWhereUniqueInput should not exist
  • PostWhereUniqueInput should not exist
  • PostCreateWithoutAuthorInput should not exist

Expected:

type Mutation {
  createOneUser(data: UserCreateInput!): User!
}

type User {
  email: String!
  id: Int!
}

input UserCreateInput {
  email: String!
}
scopprojecting scopsynchronized-projectors typbug

Most helpful comment

What if you have two different object types mapping to User? eg:

That's really interesting. From the point of view of the GQL API these are separate objects. We want to make sure that our projecting API is predictable and highly malleable. It should be easy to model different intents/patterns. I also think not cross wires between layers (ala #460) in unexpected or uncontrollable ways is core to a usable projecting API.

But, what if you do want posts to appear in UserCreateInput but you don't want to expose it in your public gql schema?

As per my response to https://github.com/prisma-labs/nexus-prisma/issues/348#issuecomment-542107424 I agree. We don't want to make a decision. What we do need I think is

  1. good API to support multiple (sane) patterns (the more granular/composable the better)
  2. good local defaults
  3. ability to override local defaults (kind of implied)
  4. ability to override defaults at global level

All 2 comments

Not sure to follow where the bug is here. In your expected snapshot, you forgot to give the definition of UserCreateInput, which is where all the PostCreate* & PostWhere* types come from.

To remove all Post* input types, PostCreateInput would need to have the following definition:

That suggests that object types that maps to model should affect how input types are published. In other words, because User don't expose t.model.posts(), UserCreateInput should not expose posts: PostCreateManyWithoutPostsInput either.

I don't think we should do that.

1)

What if you have two different object types mapping to User? eg:

const User = objectType({
  name: 'User',
  definition(t) {
    t.model.id()
    t.model.email()
  },
})

const Admin = objectType({
  name: 'Admin',
  definition(t) {
    t.model('User').id()
    t.model('User').email()
    t.model('User').posts()
  },
})

Admittedly, this could be fixed by #460.

2)

But, what if you do want posts to appear in UserCreateInput but you don't want to expose it in your public gql schema?

This is related to https://github.com/prisma-labs/nexus-prisma/issues/348#issuecomment-542107424

What if you have two different object types mapping to User? eg:

That's really interesting. From the point of view of the GQL API these are separate objects. We want to make sure that our projecting API is predictable and highly malleable. It should be easy to model different intents/patterns. I also think not cross wires between layers (ala #460) in unexpected or uncontrollable ways is core to a usable projecting API.

But, what if you do want posts to appear in UserCreateInput but you don't want to expose it in your public gql schema?

As per my response to https://github.com/prisma-labs/nexus-prisma/issues/348#issuecomment-542107424 I agree. We don't want to make a decision. What we do need I think is

  1. good API to support multiple (sane) patterns (the more granular/composable the better)
  2. good local defaults
  3. ability to override local defaults (kind of implied)
  4. ability to override defaults at global level
Was this page helpful?
0 / 5 - 0 ratings

Related issues

jasonkuhrt picture jasonkuhrt  路  4Comments

franjohn21 picture franjohn21  路  4Comments

sachaw picture sachaw  路  3Comments

jamesopti picture jamesopti  路  4Comments

aqwert picture aqwert  路  3Comments