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

Posted

技术标签:

【中文标题】Vue Apollo:变量未添加到 graphql 查询,或者我在后端没有正确接受它们(Golang)【英文标题】:Vue Apollo: variables are not added to graphql query, or I am not correctly accepting them on the backend (Golang) 【发布时间】:2019-07-19 11:53:15 【问题描述】:

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

在我的 go 后端,我为所有 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 函数。

【问题讨论】:

【参考方案1】:

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

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

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)会自动设置查询和变量

【讨论】:

感谢您的回复。我相信现在唯一阻止我解决这个问题的是如何获得rBody.Variables。也就是说,go 通知我类型 reqBody 没有字段 Variables。我一直在寻找一段时间无济于事;你知道如何从 http.Request 中检索变量吗? @EnigmaTaco struct reqBody 的类型声明是什么?您可能需要在 reqBody 中声明此字段。 reqBody 只有一个字段:type reqBody struct Query string json:"query"(我相信这是来自http 包)。我想我现在的困惑是“如何从我的 POST 请求(使用 apollo 制作)中获取变量并将它们放入 map[string]interface 类型的变量中,以便从您的答案中传递给 ExecuteQuery?” @EnigmaTaco 我不认为它来自http 包,如果是这样,它应该被命名为ReqBody。不过注意json.NewDecoder(r.Body).Decode(&rBody)不需要rBody是某个类型,你可以声明自己的类型,比如MyReqBody,里面有想要的字段,然后用它作为rBody的类型,就可以了解码后有这些值r.Body 你完全正确!我很抱歉,因为我对 Go 还是很陌生。我只需要将字段 Variables map[string]interface `json:"variables"` 添加到结构 reqBody (尽管我错误地内置在 http 包中),然后将 rBody.Variables 传递给我的 ExecuteQuery 函数,如您的答案所示。

以上是关于Vue Apollo:变量未添加到 graphql 查询,或者我在后端没有正确接受它们(Golang)的主要内容,如果未能解决你的问题,请参考以下文章

将对象数组添加到突变 react-graphql-apollo-mongoose 时,“无法读取未定义的属性 'get'”

如何在较旧的IOS /旧浏览器上使用Graphql Vue Apollo?

Vue-Apollo GraphQL Mutation 未正确调用

无法读取未定义的属性“findOne” - Vue.js、Apollo Server、GraphQL 错误

将 Strapi 连接到 NextJS/Apollo 客户端 GraphQL - 未提供所需类型“XXX”的变量“$input”

Graphql 订阅未获取客户端变量