1

我似乎无法将使用 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函数。

4

1 回答 1

0

对于您的问题,您后端接收的数据是正确的,查询本身不包含查询参数,查询参数是通过variableskey发送的。

响应问题是这一行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)会自动设置查询和变量

于 2019-02-26T03:29:40.190 回答