Я новичок в 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 какие-либо достоинства.
Заранее благодарен за ваши комментарии и предложения.
Спасибо, Дэн