go - 使用graph-gophers/graphql-go软件包的graphql变异查询错误

标签 go graphql graphql-go

问题

下面的突变

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

错误以下
{
    "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"
    }
  }
}

代码片段
schema.graphql代码段
...

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

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

type SignUpResponse {
  ok: Boolean!
  error: String
  addedUser: User
}
resolvers.go代码段
...

// 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-数据库操作
// 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
}

我试图将CreateUser更改为此
// 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
}

显然没有做到。因此出现问题,为什么查询错误?好像UserResolver无法返回User数据,前提是该行是从db返回的。

最佳答案

您的类型定义包括:

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

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

似乎您正在尝试查询返回的User的字段,但signUp不会返回User对象。相反,signUp返回一个SignUpResponse对象,作为错误状态,该对象没有任何名为emailusername的字段。

正确的查询如下所示:
mutation {
  signUp(signUpInput: {email: "newuser@gmail.com", username: "newUser", password: "asdfasdfawerawer"}) {
    addedUser {
      email
      username
    }
    ok
    error
  }
}

关于go - 使用graph-gophers/graphql-go软件包的graphql变异查询错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61853694/

相关文章:

go - 交叉编译到 ARMv7 失败

go - 安装base64时出现问题

reactjs - 没有数据的中继容器

go - "graphql.NewList(type)"是做什么的?

postgresql - golang在for循环中追加问题

go - 如何处理将另一种类型封装为参数的结构 slice

go - 测试返回值是否存在,可以是具体的也可以是 nil

graphql - 是否有可能摆脱 'data' ,'nodes' , ... 字段?

github - 如何从 github graphql 查询获取拉取请求的默认合并方法?

go - 全局变量和 Go