Graphql 字段在类型上不存在

IT技术 ruby-on-rails reactjs graphql
2021-04-30 04:20:19

在浏览了 Graphql 的文档后,我开始在玩具导轨/reactJS 项目中实现它。这些项目允许用户通过设计登录,然后访问显示艺术家列表的虚拟 /artist 路径。在我尝试使用来自 react 应用程序的 GraphQL 的 api 数据来获取艺术家并显示它们之前,一切似乎都正常工作。

在服务器端,我有一个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:

图/查询/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

类型/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 = 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)

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

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

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

我究竟做错了什么?

4个回答

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

您发送的 GQL 查询格式错误,它要求根对象query字段Query改用这个:

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

顺便说一句,您可以添加graphiqlgem ( https://github.com/rmosolgo/graphiql-rails ) 来为您的 GraphQL API 提供一个游乐场。

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

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

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