类型上不存在 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”标头