ENVIRONMENT
0.1.0
PREPARATION
Created custom models, and ran yarn rw db save and yarn rw db up -- success. Schema:
model User {
id String @id @default(cuid())
name String
email String
wkspaces Workspace[] @relation(name: "UserAsWorkspaceMember")
wkspaces_o Workspace[] @relation(name: "UserAsWorkspaceOwner")
projects Project[] @relation(name: "UserAsProjectMember")
projects_o Project[] @relation(name: "UserAsProjectOwner")
createdAt DateTime @default(now())
}
model Workspace {
id String @id @default(cuid())
name String
owner User? @relation(name: "UserAsWorkspaceOwner")
users User[] @relation(name: "UserAsWorkspaceMember")
createdAt DateTime @default(now())
}
model Project {
id String @id @default(cuid())
wkspace Workspace @relation(name: "WorkspaceAsProjectContainer")
name String
owner User @relation(name: "UserAsProjectOwner")
users User[] @relation(name: "UserAsProjectMember")
createdAt DateTime @default(now())
}
Ran yarn rw g scaffold user and yarn rw g scaffold workspace and yarn rw g scaffold
project -- all ran (after I manually patched around the "scaffold.css already exists" problem).
OBSERVED PROBLEM
When I started the server via yarn rw dev, got this error trace repeatedly:
17:56:13 api |
17:56:13 api | /Users/chris/proj/aw-hammer/node_modules/graphql/type/validate.js:71
17:56:13 api | throw new Error(errors.map(function (error) {
17:56:13 api | ^
17:56:13 api | Error: The type of ProjectInput.wkspace must be Input Type but got: Workspace.
17:56:13 api |
17:56:13 api | The type of ProjectInput.owner must be Input Type but got: User.
17:56:13 api |
17:56:13 api | The type of ProjectInput.users must be Input Type but got: User.
17:56:13 api |
17:56:13 api | The type of UserInput.wkspaces must be Input Type but got: Workspace.
17:56:13 api |
17:56:13 api | The type of UserInput.wkspaces_o must be Input Type but got: Workspace.
17:56:13 api |
17:56:13 api | The type of UserInput.projects must be Input Type but got: Project.
17:56:13 api |
17:56:13 api | The type of UserInput.projects_o must be Input Type but got: Project.
17:56:13 api |
17:56:13 api | The type of WorkspaceInput.owner must be Input Type but got: User.
17:56:13 api |
17:56:13 api | The type of WorkspaceInput.users must be Input Type but got: User.
17:56:13 api |
17:56:13 api | The type of WorkspaceInput.projects must be Input Type but got: Project.
17:56:13 api | at assertValidSchema (/Users/chris/proj/aw-hammer/node_modules/graphql/type/validate.js:71:11)
17:56:13 api | at assertValidExecutionArguments (/Users/chris/proj/aw-hammer/node_modules/graphql/execution/execute.js:136:35)
17:56:13 api | at executeImpl (/Users/chris/proj/aw-hammer/node_modules/graphql/execution/execute.js:86:3)
17:56:13 api | at Object.execute (/Users/chris/proj/aw-hammer/node_modules/graphql/execution/execute.js:64:63)
17:56:13 api | at Object.generateSchemaHash (/Users/chris/proj/aw-hammer/node_modules/apollo-server-core/src/utils/schemaHash.ts:11:18)
17:56:13 api | at ApolloServer.generateSchemaDerivedData (/Users/chris/proj/aw-hammer/node_modules/apollo-server-core/src/ApolloServer.ts:496:24)
17:56:13 api | at new ApolloServerBase (/Users/chris/proj/aw-hammer/node_modules/apollo-server-core/src/ApolloServer.ts:369:32)
17:56:13 api | at new ApolloServer (/Users/chris/proj/aw-hammer/node_modules/apollo-server-lambda/src/ApolloServer.ts:38:5)
17:56:13 api | at createGraphQLHandler (/Users/chris/proj/aw-hammer/node_modules/@redwoodjs/api/src/graphQLServer.ts:48:19)
17:56:13 api | at Object.<anonymous> (/Users/chris/proj/aw-hammer/api/src/functions/graphql.js:37:47)
error Command failed with exit code 1.
In my schema, the Workspace and Project models are like this:
model Workspace {
id String @id @default(cuid())
name String
owner User? @relation(name: "UserAsWorkspaceOwner")
users User[] @relation(name: "UserAsWorkspaceMember")
createdAt DateTime @default(now())
}
model Project {
id String @id @default(cuid())
wkspace Workspace @relation(name: "WorkspaceAsProjectContainer")
name String
owner User @relation(name: "UserAsProjectOwner")
users User[] @relation(name: "UserAsProjectMember")
createdAt DateTime @default(now())
}
That means the Projects:Workspace relation is N:1 ... each project has one workspace; each workspace can have many projects. In other words, Project.wkspace points to a Workspace.
Looking at the generated workspaces.sdl.js:
type Workspace {
id: String!
name: String!
owner: User
users: User
createdAt: DateTime!
projects: Project
}
input WorkspaceInput {
name: String
owner: User
users: User
projects: Project
}
Should projects: Project be projects: [Project] due to the 1:N relation?
I'll be honest, when we built the generators it was to make sure the tutorial worked as written, we hadn't looked into the more complex relation syntax that prisma provides. It's on our list, though!
See https://graphql.org/graphql-js/mutations-and-input-types: "Input types can't have fields that are other objects, only basic scalar types, list types, and other input types".
Here's an in-depth explanation of why this is: https://stackoverflow.com/a/55881719/763269.
Bottom line: when one model references another (think foreign keys), dumb example like this:
model Invoice {
id Int @id @default(autoincrement())
name String!
lines InvoiceLine[]
}
model InvoiceLine {
id Int @id @default(autoincrement())
quantity Int!
unitprice Float!
invoice Invoice!
}
... the input type for InvoiceLine should be like this:
input InvoiceLineInput {
quantity: Int
unitprice: Float
invoice: Int <-- NOTE THIS
}
For the input type, the type of the field that references the parent Invoice type needs to match the scalar data type (in this case, Int) of the @id field in the Invoice type.
In other words, any place the SDL generation is applying a custom type to an input type field, that's what needs to change. Input fields can be only scalars or enums (or wrappers of those).
Thanks for this! And on the off chance you have days and days of free-time available we'd be more than happy to merge a PR. 😅
I'm taking a look at a PR now, thanks for suggesting.
For those experiencing this before a fix -- an easy manual edit to SDL files bridges over this.
After running yarn rw g scaffold whatever, open whatever.sdl.js and change the type of any fields in the input WhateverInput block that reference custom types to use the (scalar) type used by the @id field in the referenced type, in place of the type name.
Like in my previous comment -- invoice: Invoice! would become invoice: String.
For me that's String since I'm using cuids; by default it would be Int.
Updating this issue Title to indicate there’s a shor-term fix included. Thanks again @chris-hailstorm
PR submitted: https://github.com/redwoodjs/redwood/pull/229
Resolved by #229
Most helpful comment
PR submitted: https://github.com/redwoodjs/redwood/pull/229