Отображение нескольких файлов схемы graphQL для отдельных преобразователей - Spring Boot - PullRequest
0 голосов
/ 23 февраля 2020

Мне трудно отделить запросы от одного файла схемы. Я хочу иметь что-то вроде этого:

car.graphqls

type Query {
    car(id: ID!): Car
}

type Car {
    id: ID!,
    name: String!
}

house.graphqls

type Query {
    house(id: ID!): House
}

type House {
    id: ID!,
    owner: String,
    street: String
}

Я много искал, но не могу найти способ написать два java класса и реализовать getHouse() в одном из них и getCar() в другом.

@Component
public class CarQuery implements GraphQLQueryResolver {

    @Autowired
    private CarService carService;

    public List<Car> getCar(final int id) {
        return this.carService.getCar(id);
    }
}

public class HouseQuery implements GraphQLQueryResolver {

    @Autowired
    private HouseService houseService;

    public List<House> getHouse(final int id) {
        return this.houseService.getHouse(id);
    }
}

Я обнаружил, что * Пакет 1018 *, который я использую, будет искать в проекте и находит все файлы схемы (которые заканчиваются на .graphqls), но код, который я показал выше, дает мне эту ошибку:

Caused by: com.coxautodev.graphql.tools.FieldResolverError: No method found with any of the following signatures (with or without one of [interface graphql.schema.DataFetchingEnvironment] as the last argument), in priority order:

  com.example.polls.resolvers.CarQuery.house(~count)
  com.example.polls.resolvers.CarQuery.getHouse(~count)

Я также нашел несколько советов, что мне нужно иметь только один Root Query в файлах схемы и расширять все другие типы Query в файлах схемы. Я пытался записать в house.graphqls что-то вроде этого, но не смог:

extend Type Query {
    house(id: ID!): House
}

Есть ли способ указать graphql и java, какой файл схемы я хочу сопоставить с каким файлом распознавателя java

Ответы [ 2 ]

1 голос
/ 29 марта 2020

Спасибо AllirionX. Ваш ответ был полезен.

Я просто хотел бы обобщить окончательное решение для всех, кто ищет ответ, как создать несколько файлов схемы с отдельными типами запросов в каждом из них и сопоставить эти типы запросов с различными Java Компоненты, использующие GraphQLQueryResolver.

Структура проекта My Spring Boot

У меня есть два файла схемы A.graphqls и B.graphqls.

A.graphqls
---------------
type Person {
  id: ID!,
  name: String
}

type Query {
  getPerson(id: Int):Person
}

type Mutation {
  createPerson(name: String):Int
}

B.graphqls
---------------
type Book {
  id: ID!,
  title: String,
  owner: Person
}

extend type Query {
  getBooks(count: Int):[Book]
}

extend type Mutation {
  deleteBook(id: Int):Int
}

schema {
  query: Query,
  mutation: Mutation
}

I объясню, что я узнал о правилах, которым мы должны следовать об этой топи c (я не гарантирую, что это все необходимо, но именно так мне удалось заставить это работать так, как я хотел, чтобы это работало).

  1. Ключом здесь является только одно определение схемы. Не имеет значения, в каком файле (A.graphqls или B.graphqls или C .graphqls ...) - Например, я добавил его в файл B.graphqls внизу.

  2. Кроме того, вы можете иметь только одно определение типа запроса в одном файле. Во всех других файлах схемы вам нужно будет расширить этот тип с помощью «расширения типа запроса» (да, я знаю, теперь это имеет смысл ...). В каком файле схемы вы делаете это основное определение для запроса, которое не имеет отношения к делу. Все в этом параграфе относится и к мутациям.

  3. Вы можете использовать тип, определенный в одном файле .graphqls, в другом файле .graphqls. Это будет признано. Таким образом, в этом примере вы можете использовать ссылку на тип Person в B.graphqls.

Java resolvers:

import com.coxautodev.graphql.tools.GraphQLQueryResolver;
import graphql.demo.model.Person;
import graphql.demo.service.PersonService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.List;

@Component
public class AQuery implements GraphQLQueryResolver {

  @Autowired
  private PersonService personService;

  public Person getPerson(final int id) {
      return this.personService.getPerson(id);
  }
}

И второй ...

@Component
public class BQuery implements GraphQLQueryResolver {

  @Autowired
  private BookService bookService;

  public List<Book> getBooks(final int count) {
      return this.bookService.getBooks(count);
  }
}

Имена этих классов не важны. У нас также может быть только один класс, реализующий GraphQLQueryResolver, и мы можем реализовать все методы запросов из файлов A.graphqls и B.graphqls (методы getBooks () и getPerson ()). Пока мы реализуем все методы, не важно, в каком классе резолвера мы его реализовали graphql- java найдет его. То же самое относится и к мутациям с использованием GraphQLMutationResolver.

У меня есть полный рабочий пример (MySQL, Spring Boot, React with Apollo client) на моем github, так что вы можете проверить его. Также есть скрипт mysql для генерации базы данных, используемой в проекте. Существует множество таблиц, но есть только для целей тестирования, важна структура файлов и файлов, которые я объяснил выше. Если вас не интересует клиентское приложение, вы можете, конечно, протестировать его с помощью graphiql.

https://github.com/dusko-dime/spring-react-graphql

Надеюсь, это кому-нибудь пригодится, и спасибо, что помогли мне еще раз :)

0 голосов
/ 18 марта 2020

Несколько файлов схемы

Graphql-java-tools найдет все файлы .graphqls для построения экземпляра схемы. Несколько файлов схемы работают "из коробки".

Несколько распознавателей

Каждый компонент распознавателя должен реализовывать GraphQLQueryResolver или GraphQLMutationResolver и быть сканируемым при весенней загрузке. Убедитесь, что он имеет аннотацию @Component и находится в одном из пружинных @ComponentScan basePackages.

Ошибка

No method found with any of the following signature означает, что graphql-tools не удалось найти преобразователь Компонент с методом, соответствующим сигнатурам. В этом случае в преобразователе HouseQuery отсутствует аннотация @Component.

...