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