Spring Boot / GraphQL и количество операторов SQL (выпуск N + 1) - PullRequest
2 голосов
/ 20 января 2020

Я новичок в Graphql и изучаю возможность создания концепции, чтобы понять, как она работает. Я использую Spring Boot (2.2.2.RELEASE) и ввожу graphql-spring-boot-starter.

    <dependency>
        <groupId>com.graphql-java-kickstart</groupId>
        <artifactId>graphql-spring-boot-starter</artifactId>
        <version>6.0.1</version>
    </dependency>

Я настроил мою схему graphql в виде файла на пути к классам со следующей конфигурацией:

type Order {
  orderNumber: ID!
  customers: [Customer]
  items: [Item]
}

type Customer {
  customerNumber: ID!
  fullName: String
  postalAddresses: [PostalAddress]
}

type PostalAddress {
  line1: String
  line2: String
  city: String
  stateCode: String
  postalCode: String
  postalCodeExtension: String
  countryCode: String
}

type Item {
  itemId: ID!
  fullDescription: String
}

type Query {
  findOrdersByCustomerNumber(customerNumber: String): [Order]
}

Я создал root Класс запросов:

@Component
public class Query implements GraphQLQueryResolver {
    private OrderService orderService;

    @Autowired
    public Query(OrderService orderService) {
        this.orderService = orderService;
    }

    public List<Order> findOrdersByCustomerNumber(String customerNumber) {
        return this.orderService.findOrdersByCustomerNumber(customerNumber);
    }
}

А вот мой распознаватель заказов:

@Component
public class OrderResolver implements GraphQLResolver<Order> {
    private ItemRepository itemRepository;
    private CustomerRepository customerRepository;

    @Autowired
    public OrderResolver(CustomerRepository customerRepository, ItemRepository itemRepository) {
        this.customerRepository = customerRepository;
        this.itemRepository = itemRepository;
    }

    public List<Item> item(Order order) {
        return itemRepository.findItemsByOrderNumber(order.getOrderNumber());
    }

    public List<Customer> customers(Order order) {
        return customerRepository.findCustomersByOrderNumber(order.getOrderNumber());
    }
}

Кажется, все работает нормально и Я могу отправить запрос graphql и получить ответ. На самом деле это было действительно легко реализовать, и я был поражен тем, как быстро эта библиотека позволила мне сделать это.

Однако, вот моя проблема. Это страшная проблема n + 1 SQL.

Итак, когда у меня есть клиент с 162 заказами.

  1 = Driver SQL (get all the orders for the customer number)
162 = Customer SQL (One query is fired off for each order and it's same customer for each select)
162 = Postal Address SQL (One query is fired off for each customer...note, not included in the code snippets)
162 = Item SQL (assume one item per order).

Итак, это всего 487 SQL запросов. И, как результат, это влияет на производительность. Я использую прямую JDB C для запроса к базе данных (на данный момент нет JPA или ORM).

У меня вопрос, как мне получить запрос GraphQL в решателе root Query, чтобы манипулировать SQL для зависимых объектов в графе? Проводя некоторые исследования, я вижу, что в мире Node / Javacript есть утилита загрузки данных, которая может помочь решить эту проблему (https://github.com/graphql/dataloader)

Итак, мне неясно, как решить эту проблему с помощью этой java реализации. Если у кого-то есть какие-либо предложения или пример кода, было бы очень полезно узнать, имеет ли этот PO C какие-либо достоинства.

Заранее благодарен за ваши комментарии и предложения.

Спасибо, Дэн

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...