Поле Graphql не существует для типа

После беглого просмотра документации Graphql я начал реализовывать его в проекте игрушечных рельсов / reactJS. Проекты позволяют пользователю войти в систему через devise, а затем получить доступ к маршруту фиктивного / исполнителя, который отображает список художников. Кажется, все работает нормально, пока я не попытаюсь использовать данные api с помощью 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

Затем, следуя логике моей модели, я настроил graphql в разделе graph / со следующими файлами:

график / запросы / 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.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.info(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 для graphql, я (конечно) получаю код ошибки 422 и следующее сообщение об ошибке:

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

Я предполагаю, что мой запрос выполнен неправильно. Я пробовал различные форматы запросов (из примеров документации или gists), но не могу найти правильный способ вернуть данные моего исполнителя.

Что я делаю неправильно?

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
9
0
15 791
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Отправленный вами запрос GQL имеет неправильный формат, он запрашивает поле query корневого объекта Query. Используйте вместо этого:

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

Кстати, вы можете добавить гем graphiql (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 без представлений.

gastngouron 01.10.2018 19:02

Ладно, проблема не в самом коде. Я изменил запрос на тот, который вы посоветовали, и обновил имена художников на что-то другое как на стороне клиента, так и на стороне сервера. Кажется, что apollo-rails кэширует предыдущие вызовы api, даже если они не удались, поэтому я всегда получал одну и ту же ошибку. Мне еще предстоит выяснить, как очистить этот кеш. Спасибо за ваше время.

Ответ принят как подходящий

Я не думаю, что это проблема в данном конкретном случае, но я получал эту ошибку, и она оказалась из-за простой синтаксической ошибки. Атрибуты запроса должны быть в формате camelCase, а не в формате подчеркивания. Может быть, это поможет кому-то еще, кто попадет сюда при поиске этой ошибки, как это сделал я.

Ооо, я провел час или больше, не понимая, почему мое второе возвращенное поле сработало ... вот оно что. Дох. Спасибо

GigaBass 18.03.2020 17:17

Угу, это убивало меня больше часа. Спасибо вам большое за размещение этого!

codeadventurer 29.05.2020 20:56

У меня была эта ошибка в RSpec, но не при реальном вызове, т.е. Postman, для того же запроса. Решением было изменить запрос в спецификации с

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

к

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

Однако в других спецификациях первый подход работал с похожей мутацией, поэтому я не уверен, что было не так.

В моем случае проблема заключалась в том, что у меня была такая структура:

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

НО в запросе у меня была другая вложенная структура под названием данные, о которой я забыл:

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

Другие вопросы по теме