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

Updates GraphQL SDL Required Types logic #432

Merged
merged 5 commits into from
Apr 14, 2020
Merged

Conversation

cannikin
Copy link
Member

@cannikin cannikin commented Apr 14, 2020

Following discussions in #316 and #324 I made some updates to the SDL generators. Assuming the following schema.prisma definition:

model Post {
  id       Int      @id @default(autoincrement())
  title    String
  slug     String @unique
  author   String
  body     String
  image    String?
  postedAt DateTime?
}

Currently Redwood generates a CRUD SDL that looks like:

export const schema = gql`
  type Post {
    id: Int!
    title: String!
    slug: String!
    author: String!
    body: String!
    image: String
    postedAt: DateTime
  }

  type Query {
    posts: [Post]
    post(id: Int!): Post
  }

  input PostInput {
    title: String
    slug: String
    author: String
    body: String
    image: String
    postedAt: DateTime
  }

  type Mutation {
    createPost(input: PostInput!): Post
    updatePost(id: Int!, input: PostInput!): Post
    deletePost(id: Int!): Post
  }
`

Note that no input types are required in PostInput even though they are required in the schema. If you try to save this record, Prisma will throw up a pretty gross error that isn't immediately clear what happened. After pondering the discussion in #316 I discussed with @mojombo and we like the idea proposed by @weaversam8 in which there are two input types, one for Create where everything that's required in schema.prisma is also required in GraphQL, as well as an Update where no fields are required:

input CreatePostInput {
  title: String!
  slug: String!
  author: String!
  body: String!
  image: String
  postedAt: DateTime
}

input UpdatePostInput {
  title: String
  slug: String
  author: String
  body: String
  image: String
  postedAt: DateTime
}

type Mutation {
  createPost(input: CreatePostInput!): Post!
  updatePost(id: Int!, input: UpdatePostInput!): Post!
  deletePost(id: Int!): Post!
}

This is a developer experience decision. If you have a database table with 50 columns, all of which are required for a record to exist, you obviously must provide all of them to create a record. However if you only want to edit a single one, you don't want to have to also send along the 49 other required fields along with the 1 you actually need to change. If you absolutely want your GraphQL interface to provide only mutations for each individual field you are free to create 50 Update input types, one for each field.


This PR also covers some suggestions in #324 where returns in Query types are required.

Currently:

  type Query {
    posts: [Post]
    post(id: Int!): Post
  }

This pull request changes that to:

  type Query {
    posts: [Post!]!
    post(id: Int!): Post!
  }

So on posts you know you'll always get an array, and those array elements will only be of type Post. Likewise the post query will always return a Post.

@cannikin cannikin merged commit a3f5ec2 into master Apr 14, 2020
@cannikin cannikin deleted the rc-graphql-required-types branch April 14, 2020 23:14
@thedavidprice thedavidprice added this to the unassigned-version milestone May 14, 2021
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

Successfully merging this pull request may close these issues.

None yet

3 participants