Vue Apollo:变量没有添加到 graphql 查询,或者我没有在后端正确接受它们(Golang)

Vue Apollo: variables are not added to graphql query, or I am not correctly accepting them on the backend (Golang)

我似乎无法将使用 apollo 进行的 graphql 查询中的变量放入查询主体以被后端服务器接受。

我有一个简单的 vue 前端和后端。在 vue 组件中,我有以下查询:

apollo: {
    entry: {
      query: gql`
        query variables($userID: Int){
          entries(userID: $userID) {
            id,
            value,
            timeStamp
          }
        }
      `,
      variables() {
        return {
          userID: 2
        }
      },

      update: data => data,
    }
  }
}

在我的后端,我为所有 POST 请求设置了处理函数

// GraphQL returns an http.HandlerFunc for our /graphql endpoint
func (s *Server) GraphQL() http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        //Allow CORS here By * or specific origin
        w.Header().Set("Access-Control-Allow-Origin", "*")

        w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
        // Check to ensure query was provided in the request body
        if r.Body == nil {
            http.Error(w, "Must provide graphql query in request body", 400)
            return
        }

        var rBody reqBody
        // Decode the request body into rBody
        err := json.NewDecoder(r.Body).Decode(&rBody)
        if err != nil {
            http.Error(w, "Error parsing JSON request body", 400)
        }

        fmt.Println(rBody.Query)

        // Execute graphql query
        result := gql.ExecuteQuery(rBody.Query, *s.GqlSchema)

        // render.JSON comes from the chi/render package and handles
        // marshalling to json, automatically escaping HTML and setting
        // the Content-Type as application/json.
        render.JSON(w, r, result)
    }
}

当我 运行 查询时,返回 {"entries" : null}。当我打印出发送到我的 go 服务器的查询时,我得到以下信息:

query variables($userID: Int) {
  entries(userID: $userID) {
    id
    value
    timeStamp
    __typename
  }
}

在第 2 行中,我希望看到条目(用户 ID:2)。事实上,如果我从 vue 中的查询中删除变量,并在查询中硬编码用户 ID,一切正常。

我检查以确保变量正在以某种方式发送,如果我查看 POST 请求,它在参数中包含以下内容:

operationName   variables
query   query variables($userID: Int) { entries(userID: $userID) { id value timeStamp __typename } }
variables   {…}
userID  2

我是否没有在后端正确接受数据,因为变量 userID 是在 POST 请求中发送的?

解决方法: 感谢@cgcgbcbc 提供解决方案。我的 reqBody 结构如下:

type reqBody struct {
    Query     string                 `json:"query"`
}

什么时候应该是:

type reqBody struct {
    Query     string                 `json:"query"`
    Variables map[string]interface{} `json:"variables"`
}

然后我只需要像他的解决方案一样将 rBody.Variables 传递给我的 ExecuteQuery 函数。

对于你的问题,你后台接收的数据是正确的,查询本身不包含查询参数,查询参数是通过variables键发送的。

响应问题是这一行result := gql.ExecuteQuery(rBody.Query, *s.GqlSchema)。 请求正文中的 variables 也需要传递给 ExecuteQuery。使用 graphql-go/graphql Do 函数的示例实现可以是

func executeQuery(query string, schema graphql.Schema, variables map[string]interface{}) *graphql.Result {
    result := graphql.Do(graphql.Params{
        Schema:        schema,
        RequestString: query,
        VariableValues: variables
    })
    if len(result.Errors) > 0 {
        fmt.Printf("errors: %v", result.Errors)
    }
    return result
}

类型reqBody的例子可以是

type reqBody struct {
    Query string
    Variables map[string]interface{}
}

然后json.NewDecoder(r.Body).Decode(&rBody)会自动设置Query和Variables