类型上不存在 Graphql 字段

Posted

技术标签:

【中文标题】类型上不存在 Graphql 字段【英文标题】:Graphql Field doesn't exist on type 【发布时间】: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"]]

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

我做错了什么?

【问题讨论】:

【参考方案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

【讨论】:

以上是关于类型上不存在 Graphql 字段的主要内容,如果未能解决你的问题,请参考以下文章

Mongoose 和 TypeScript - 类型“事件模型”上不存在属性“_doc”

FB Graph API - 尝试访问节点类型上不存在的字段(反应)(照片)

Facebook 错误:“(#100) 尝试访问节点类型 (User) 上不存在的字段 (user_friends)”

在 ng build--aot 期间,类型“any []”上不存在属性“名称”

无法在 React 中使用 GraphQL 查询 - 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头

“typeof Schema”类型上不存在属性“virtual”