【问题标题】:Graphql Field doesn't exist on type类型上不存在 Graphql 字段
【发布时间】:2019-03-06 19:48:18
【问题描述】:

在浏览了 Graphql 的文档后,我开始在一个玩具 rails/reactJS 项目中实现它。这些项目允许用户通过设计登录,然后访问显示艺术家列表的虚拟/艺术家路线。在我尝试使用来自 react 应用程序的 GraphQL 来获取艺术家并显示它们之前,一切似乎都运行良好。

在服务器端,我有一个 graphql_controller.rb 例如:

class GraphqlController < ApiController
  rescue_from Errors::Unauthorized do |exception|
    render json: {errors: ['Unauthorized.']}, status: :unauthorized
  end

  def index
    result = Schema.execute params[:query], variables: params[:variables], context: context
    render json: result, status: result['errors'] ? 422 : 200
  end

private

  def context
    token, options = ActionController::HttpAuthentication::Token.token_and_options request
    {
      ip_address: request.remote_ip
    }
  end
end

然后,按照我的模型逻辑,我在 graph/ 下使用以下文件设置了 graphql:

graph/queries/artist_query.rb

ArtistQuery = GraphQL::ObjectType.define do
  name 'ArtistQuery'
  description 'The query root for this schema'

  field :artists, types[Types::ArtistType] do
    resolve(->(_, _, _) {
      Artist.all
    })
  end
end

types/artist_type.rb

Types::ArtistType = GraphQL::ObjectType.define do
  name 'Artist'
  description 'A single artist.'

  field :id, !types.ID
  field :name, types.String
  field :description, types.String
end

schema.rb

Schema = GraphQL::Schema.define do
  query ArtistQuery
end

在客户端,为了保持井井有条,我使用 3 个文件来呈现这个艺术家列表:

首先,ArtistSchema.js

import { gql } from 'react-apollo';

const artistListQuery = gql`
    {
        query {
            artists {
                id
                name
                description     
            }
        }
    }
`;

export default artistListQuery;

然后,一个Artist.js

import React, { Component } from 'react';

class Artist extends Component {
    render() {
        return (
            <tr>
                <td>{this.props.index + 1}</td>
                <td>{this.props.data.name}</td>
                <td>{this.props.data.description} min</td>
            </tr>
        );
    }
}

export default Artist;

最后,将这两个封装在一个更大的布局中:Artists.jsx

import React, { Component } from 'react';
import {graphql} from 'react-apollo';
import Artist from './Artist';
import artistListQuery from './ArtistSchema';

class Artists extends Component {
    render() {
        if(this.props.data.loading) {
            return (<p>Loading</p>)
        } else {

            console.log(this.props.data)
            const ArtistsItems = this.props.data.artists.map((data,i) => {
                return (<Artist key={i} index={i} data={data}></Artist>);
            });
            return (
                <div>
                    <h1>Artists</h1>
                    <table className="table table-striped table">
                        <thead>
                        <tr>
                            <th>#</th>
                            <th>Name</th>
                            <th>Description</th>
                        </tr>
                        </thead>
                        <tbody>
                        { ArtistsItems }
                        </tbody>
                    </table>
                </div>
            );
        }

    }
}

export default graphql(artistListQuery)(Artists);

执行这段代码会发生什么:

在服务器端(抱歉输出未格式化,但它在控制台中显示如下):

Processing by GraphqlController#index as */*
18:49:46 api.1  |   Parameters: {"query"=>"{\n  query {\n    artists {\n      id\n      name\n      description\n      __typename\n    }\n    __typename\n  }\n}\n", "operationName"=>nil, "graphql"=>{"query"=>"{\n  query {\n    artists {\n      id\n      name\n      description\n      __typename\n    }\n    __typename\n  }\n}\n", "operationName"=>nil}}

后面跟着错误:

Completed 422 Unprocessable Entity in 36ms (Views: 0.2ms | ActiveRecord: 0.0ms)

在客户端,如果我监控 Network > Response for graphql,我(当然)会收到 422 错误代码和以下错误消息:

{"errors":[{"message":"Field 'query' doesn't exist on type 'ArtistQuery'","locations":[{"line":2,"column":3}],"fields":["query","query"]}]}

我假设我的查询没有正确完成。我一直在尝试各种查询格式(来自文档或要点示例),但我无法找到正确的方法来取回我的艺术家数据。

我做错了什么?

【问题讨论】:

    标签: ruby-on-rails reactjs graphql


    【解决方案1】:

    我认为这不是这个特殊情况的问题,但我收到了这个错误,结果证明是一个简单的语法错误。 查询属性需要采用 camelCase 格式,而不是 under_score 格式。也许这会帮助其他人在像我一样搜索此错误时到达这里。

    【讨论】:

    • 哎呀我花了一个小时或更长时间不明白为什么我的第二个返回字段工作......就是这个。多哈。谢谢
    • Ugggggggh 这让我死了一个多小时。非常感谢你发布这个!
    • 这是 da....m 对!!!!谢谢
    【解决方案2】:

    您发送的 GQL 查询格式不正确,它要求 query 根对象的 query 字段。改用这个:

    const artistListQuery = gql`
        query UseTheNameYouWantHere {
            artists {
                id
                name
                description     
            }
        }
    `;
    

    顺便说一句,您可以添加 graphiql gem (https://github.com/rmosolgo/graphiql-rails) 来使用您的 GraphQL API。

    【讨论】:

    • 非常感谢您的回答,但我之前尝试过,按照您的建议执行操作会导致客户端出现错误,例如:apollo.umd.js:1409 Uncaught Error: Encountered a sub-selection on the query, but the store doesn't have an object reference. This should never happen during normal use unless you have custom code that is directly manipulating the store; please file an issue. 当我使用查询时,服务器甚至没有收到请求您提供的代码。关于游戏提供的 graphiql 客户端,我无法访问它,因为我的应用是没有视图的 api。
    【解决方案3】:

    就我而言,问题是我有这样的结构:

    module Types
      class SomeType < Types::BaseObject
        field :comparator,
              Types::ComparatorType
        field :options,
              [Types::OptionType]
      end
    end
    

    但在查询中,我忘记了其他名为 data 的嵌套结构:

    mutation {
      myMutation(
        ...  
      ) {
        someType {
          comparator {
            ...
          }
          data {
            options {
               ...
            }
          }
        }
      }
    }
    

    所以在更改 SomeType 类以添加缺少的密钥后解决了我的问题。所以现在看起来像这样:

    module Types
      class SomeType < Types::BaseObject
        field :comparator,
              Types::ComparatorType
        field :data,
              Types::DataType
      end
    end
    
    # New file
    module Types
      class DataType < Types::BaseObject
        field :options,
              [Types::OptionType]
      end
    end
    

    【讨论】:

      【解决方案4】:

      好吧,问题不在于代码本身。我将查询更改为您建议的查询,并将名称艺术家更新为客户端和服务器端的其他名称。 似乎 apollo-rails 正在缓存以前的 api 调用,即使它们失败了,这就是为什么我总是得到同样的错误。我仍然需要弄清楚如何清理这个缓存。感谢您的宝贵时间。

      【讨论】:

        【解决方案5】:

        我在 RSpec 中遇到了这个错误,但在实际调用中没有,例如 Postman,对于相同的查询。解决方案是将规范中的查询从

        <<~QUERY
          query users {
            posts {
              ...
            }
          }
        QUERY
        

        <<~QUERY
          query users {
            users {
              posts {
                ...
              }
            }
          }
        QUERY
        

        但是在其他规范中,第一种方法是处理外观相似的突变,所以我不确定出了什么问题

        【讨论】:

          【解决方案6】:

          您可能需要使用更新的 API 端点 URL 版本。

          示例请求 URL:https://shopify-graphiql-app.shopifycloud.com/api/*2022-01*/graphql

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2021-11-16
            • 2020-01-02
            • 2020-12-04
            • 1970-01-01
            • 2020-10-20
            • 2021-11-13
            • 2020-05-29
            • 2021-03-17
            相关资源
            最近更新 更多