Search code examples
graphqlapolloapollo-serverprismaprisma-graphql

Am getting 'Variable '$data' expected value of type 'UserCreateInput!'' when attempting Prisma GraphQL 'createUser'


I did a couple of sites with GraphQL-Yoga and Prisma a little while ago and am attempting the same with Apollo Express. All worked fine. Now however I can't get the thing started -- perhaps I'm going too fast and attempting too many things at once. I am starting trying to implement a registration mutation following this guide. My first (and for the moment only) mutation is

const resolvers = {
  Mutation: {
    register: async (parent, { username, password }, ctx, info) => {
      const hashedPassword = await bcrypt.hash(password, 10)
      const user = await ctx.prisma.createUser({
        username,
        password: hashedPassword,
      })
      return user
    },
  },
}

but when I test it in GraphQL Playground

mutation {
 register(username:"foo",password: "bar") {
  id
  username
}
}

I get this error

"errors": [
    {
      "message": "Variable '$data' expected value of type 'UserCreateInput!' but got: {\"username\":\"sandor\",\"password\":\"$2a$10$S7IF1L3YjS4dLUm8QB2zjenPnKHwlohml7AaPf1iVhNipHSkNb/62\"}. Reason: 'name' Expected non-null value, found null. (line 1, column 11):\nmutation ($data: UserCreateInput!) {\n          ^",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "register"
      ],
      "extensions": {
        "code": "INTERNAL_SERVER_ERROR",

I looked in `generated/prisma-client/prisma-schema´ and see that I have

  createUser(data: UserCreateInput!): User!

But when I used Prisma before it never complained about expecting an input type when I passed it an object. Where am I going wrong here?

My schema is

const { gql } = require('apollo-server-express');


const typeDefs = gql`

  type User {
    id: ID!
    username: String!
    password: String!
  }

  type Query {
    currentUser: User!
  }

  type Mutation {
    register(username: String!, password: String!): User!
    login(username: String!, password: String!): LoginResponse!
  }

  type LoginResponse {
    id: ID!
    token: String
    user: User
  }

`
module.exports = typeDefs

and my datamodel.prisma is

type User {
  id: ID! @id
  name: String!
    password: String!

}


type LoginResponse {
     id: ID! @id
    token: String
    user: User
}

I am sure I'm missing something blindingly obvious, but after looking some time I don't see it -- so any clue would be much appreciated!


Solution

  • The answer -- hinted at by @Errorname in a comment and given to me by a user on the Prisma Spectrum forum (I didn't see it myself), is that there was a discrepancy between the Prisma datamodel and the GraphQL schema. To wit, the field was being called 'username' in the schema, and 'name' in the datamodel. I changed it to 'username' in the datamodel. Doh!

    type User {
      id: ID! @id
      username: String!
      password: String!
    }
    

    and it works fine! I didn't need to add the 'data' object to createUser, as suggested by @Errorname above -- that is, this works fine

     Mutation: {
        register: async (parent, {username, password}, ctx, info) => {
          const hashedPassword = await bcrypt.hash(password, 10)
          const user = await ctx.prisma.createUser({
    
              username,
              password: hashedPassword,
    
          })
          return user
        },
      },