简体   繁体   中英

graphql mutation query error using graph-gophers/graphql-go package

PROBLEM

the mutation below

mutation {
  signUp(signUpInput: {email: "newuser@gmail.com", username: "newUser", password: "asdfasdfawerawer"}) {
    email
    username
  }
}

errors out the following

{
    "errors": [
        {
            "message": "Cannot query field \"email\" on type \"SignUpResponse\".",
            "locations": [
                {
                    "line": 3,
                    "column": 5
                }
            ]
        },
        {
            "message": "Cannot query field \"username\" on type \"SignUpResponse\".",
            "locations": [
                {
                    "line": 4,
                    "column": 5
                }
            ]
        }
    ]
}

EXPECTATION

{
  "data": {
    "signUp": {
      "email": "newuser@gmail.com",
      "username": "newUser"
    }
  }
}

snippets of code

schema.graphql snippet

...

input SignUpInput {
  username: String!
  email: String!
  password: String!
}

type Mutation {
  signUp(signUpInput: SignUpInput): SignUpResponse!
}

type SignUpResponse {
  ok: Boolean!
  error: String
  addedUser: User
}

resolvers.go snippet

...

// UserResolver ingests properties from User
type UserResolver struct{ u *User }

// UserID returns the userId of the user
func (r *UserResolver) UserID() graphql.ID {
    return r.u.UserID
}

// Username returns the username of the user
func (r *UserResolver) Username() string {
    return r.u.Username
}

// Email returns the email of the user
func (r *UserResolver) Email() string {
    return r.u.Email
}

// Password returns the password of the user
func (r *UserResolver) Password() string {
    return r.u.Password
}

type SignUpArgs struct {
    Username string
    Email    string
    Password string
}

// SignUp returns a new User from Db and its responses
func (r *RootResolver) SignUp(args struct{ SignUpInput *SignUpArgs }) (*SignUpResolver, error) {
    // Find user:
    u, err := r.Db.CreateUser(args.SignUpInput)
    // need to deal with this different, so sort of error if we can't create the user
    // a. user already exists
    // b. email already exists
    if err != nil {
        // error creating the user
        msg := "already signed up"
        return &SignUpResolver{
            Status: false,
            Msg:    &msg,
            User:   nil,
        }, err
    }

    return &SignUpResolver{
        Status: true,
        Msg:    nil,
        User:   &UserResolver{&u},
    }, nil
}

// SignUpResolver is the response type
type SignUpResolver struct {
    Status bool
    Msg    *string
    User   *UserResolver
}

// Ok for SignUpResponse
func (r *SignUpResolver) Ok() bool {
    return r.Status
}

// Error for SignUpResponse
func (r *SignUpResolver) Error() *string {
    return r.Msg
}

// AddedUser for SignUpResponse
func (r *SignUpResolver) AddedUser() *UserResolver {
    return r.User
}

postgres.go - db operations

// User returns a single user
func (d *Db) User(uid graphql.ID) (User, error) {
    var (
        sqlStatement = `SELECT * FROM users WHERE user_id=$1;`
        row          *sql.Row
        err          error
        u            User
    )
    row = d.QueryRow(sqlStatement, uid)
    err = row.Scan(
        &u.UserID,
        &u.Username,
        &u.Email,
        &u.Password,
    )
    util.Check(err, "row.Scan")
    return u, nil
}

// CreateUser - inserts a new user
func (d *Db) CreateUser(i *SignUpArgs) (User, error) {
    var (
        sqlStatement = `
            INSERT INTO users (email, username, password)
            VALUES ($1, $2, $3)
            RETURNING user_id`
        userID graphql.ID
        row    *sql.Row
        err    error
        u      User
    )
    /***************************************************************************
        * retrieve the UserID of the newly inserted record
        * db.Exec() requires the Result interface with the
                LastInsertId() method which relies on a returned value from postgresQL
        * lib/pq does not however return the last inserted record
    ****************************************************************************/
    row = d.QueryRow(sqlStatement, i.Email, i.Username, i.Password)
    if err = row.Scan(&userID); err != nil {
        // err: username or email is not unqiue --> user already exsits
        return u, err
    }

    u, _ = d.User(userID)
    return u, nil
}

I've tried to change the CreateUser to this

// CreateUser - inserts a new user
func (d *Db) CreateUser(i *SignUpArgs) (User, error) {
    var (
        sqlStatement = `
            INSERT INTO users (email, username, password)
            VALUES ($1, $2, $3)
            RETURNING user_id`
        userID graphql.ID
        row    *sql.Row
        err    error
        u      User
    )
    /***************************************************************************
        * retrieve the UserID of the newly inserted record
        * db.Exec() requires the Result interface with the
                LastInsertId() method which relies on a returned value from postgresQL
        * lib/pq does not however return the last inserted record
    ****************************************************************************/
    row = d.QueryRow(sqlStatement, i.Email, i.Username, i.Password)
    if err = row.Scan(&userID); err != nil {
        // err: username or email is not unqiue --> user already exsits
        return u, err
    }
    err = row.Scan(
        &u.UserID,
        &u.Username,
        &u.Email,
        &u.Password,
    )
    util.Check(err, "row.Scan User")
    return u, nil
}

didn't do it obviously.hence the question, why the query error? seems like UserResolver can't return the User data provided the row is being returned from db.

Your type definitions include:

type Mutation {
  signUp(signUpInput: SignUpInput): SignUpResponse!
}

type SignUpResponse {
  ok: Boolean!
  error: String
  addedUser: User
}

It appears you're attempting to query the fields for the returned User , but signUp does not return a User object. Instead, signUp returns a SignUpResponse object, which, as the error states, does not have any fields named email or username .

The correct query would look something like this:

mutation {
  signUp(signUpInput: {email: "newuser@gmail.com", username: "newUser", password: "asdfasdfawerawer"}) {
    addedUser {
      email
      username
    }
    ok
    error
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM