maoosi/prisma-appsync

Issue: Nested one-to-many creates don't infer the connected model

Tenrys opened this issue · 7 comments

Tenrys commented

With this schema:

datasource db {
  provider = "postgresql"
  url      = env("DATABASE_URL")
}

generator client {
  provider      = "prisma-client-js"
  binaryTargets = ["native", "rhel-openssl-1.0.x"]
  // previewFeatures = ["clientExtensions"]
}

generator appsync {
  provider = "prisma-appsync"
}

model User {
  uuid      String   @id @default(uuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  name String

  post Post[]
}

model Post {
  uuid      String   @id @default(uuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  content String

  userUuid String @unique
  user     User   @relation(fields: [userUuid], references: [uuid])
}

And this query:

mutation MyMutation {
  createUser(data: {name: "test user", post: {create: {content: "test post"}}}) {
    name
    post {
      content
    }
  }
}

Because user is required on a Post, when you try to create one at the same time as updating or creating a User, it uses the model's normal <Model>CreateInput which requires to a user relationship again, giving this error:

{
  "errors": [
    {
      "message": "Field \"PostCreateInput.user\" of required type \"PostUserCreateRelationInput!\" was not provided.",
      "locations": [
        {
          "line": 2,
          "column": 55
        }
      ]
    }
  ]
}

Prisma has a lot of different types for nested relation mutations, like PostCreateWithoutUserInput. Maybe we should try to see how to best replicate them as input types and use them everywhere relevant to try and maximize similar behavior?

The workaround for this currently, if you're updating a model, is to create the model and connect it manually.

Tenrys commented

I should note that this isn't just a feature request, because if you actually add the user in the query, you will get a different error from Prisma itself rather than GraphQL, because it does not expect it since it already infers who the created model will be for.

Thanks for solving this issue when creating a user + nested post, see https://github.com/maoosi/prisma-appsync/tree/feat/create-without
But it still does not work for the updateUser + create nested post mutation. Could you consider this as well? Would be awesome!

mutation MyMutation {
  updateUser(where: {id: "1234"}, data: {name: "test user", post: {create: {content: "test post"}}}) {
    name
    post {
      content
    }
  }
}

Another issue is that duplicate graphql ...CreateWithout...Input fields are generated when referring to the same entity > 1

model User {
  uuid      String   @id @default(uuid())
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt

  name String

  post Post[]
  anotherPost Post[]
}

This field will be generated twice:

input PostCreateWithoutUserInput {
....
}
maoosi commented

@StephanDecker I started working on a fix here, but it is not ready to use just yet.

Good catch on the duplicate! Happy for you to open a PR if you want to work on this, otherwise I'll continue working on the fix after the next release.

Are there any news on this? I see there is a feat/without branch, is it related? Any way to use it yet?

@Tenrys yes, it's related and almost ready for release. The packages/generator has been completely rewritten using a new approach, which will resolve multiple issues simultaneously, including this one.

It will be included in the first stable release (transitioning out of RC). You can test it now by installing prisma-appsync@1.0.0-preview.8.9.

Released in v1.0.0.