так что у меня есть этот класс в котлине:
@Component
class UserResolver @Autowired
constructor(private val userService: UserService): GraphQLMutationResolver, GraphQLQueryResolver {
fun createUser(user: User): User {
userService.save(user)
return user
}
fun users(): Page<User> {
val pageable = QPageRequest(0, 10)
return userService.all(pageable)
}
}
Я хочу, чтобы пользователи метода возвращали объект Page, я совершенно новичок в graphql. Я пробовал что-то вроде этого:
type Page {
number: Int
size: Int
numberOfElements: Int
content: []
hasContent: Boolean
isFirst: Boolean
isLast: Boolean
hasNext: Boolean
hasPrevoius: Boolean
totalPages: Int
totalElements: Float
}
но мое весеннее загрузочное приложение не запускается, я не знаю, как должно выглядеть определение моей схемы для этого класса https://docs.spring.io/spring-data/commons/docs/current/api/org/springframework/data/domain/Page.html. Есть у кого-нибудь идеи?
Редактировать: ошибка:
Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.coxautodev.graphql.tools.SchemaParser]: Factory method 'schemaParser' threw exception; nested exception is com.coxautodev.graphql.tools.TypeClassMatcher$RawClassRequiredForGraphQLMappingException: Type org.springframework.data.domain.Page<sk.matusko.wixit.common.dao.User > cannot be mapped to a GraphQL type! Since GraphQL-Java deals with erased types at runtime, only non-parameterized classes can represent a GraphQL type. This allows for reverse-lookup by java class in interfaces and union types.
@pipo_dev отредактировал





За последние несколько месяцев обработка дженериков немного изменилась с появлением GraphQL Java Tools. Какую версию ты используешь? Я просто попробовал это с версией 5.4.1, и мне показалось, что это сработало, но с 5.2.4 это не помогло. Интересно, может ли быть связано исправление проблемы это.
В случае, если это поможет, вот тестовые материалы, которые я использовал:
Во-первых, я объявил такой класс: class Page<T>(val number: Int, val size: Int)
Во-вторых, в резольвере у меня был fun users() = Page<User>(...)
В-третьих, в файле схемы GraphQL у меня было это
type Page {
number: Int
size: Int!
}
type Query {
users: Page
}
Ограничение, связанное с приведенным выше, заключается в том, что у вас есть единственный тип в схеме GraphQL, который просто называется Page. Но, возможно, вам нужно что-то конкретное об объектах User? Это должно быть в свойстве content в вашем примере? Если это так, я думаю, вам нужно объявить отдельный тип в схеме GraphQL для каждого типа, который вы можете передать в параметр универсального типа Page, например UserPage, CustomerPage и т. д. Затем в коде каждый из них должен быть сопоставлен с правильным классом Kotlin, например Page<User>, Page<Customer>. Я не знаю, как сделать это в коде, не имея конкретной реализации каждого из дженериков (надеюсь, если возможно, кто-то другой может объяснить, как это сделать). Имена типов GraphQL объединяются с именами классов Kotlin по умолчанию, если у них такое же имя, или с использованием явно предоставленного сопоставления при сборке Schema с использованием SchemaParser.newParser().dictionary(....
Итак, если вам нравится создавать конкретные подклассы универсального класса для каждого типа, который вы ему предоставляете, вы можете сделать что-то вроде этого:
open class Page<T>(val number: Int, val size: Int, val content: List<T>)
class UserPage(number: Int, size: Int, content: List<User>): Page<User>(number, size, content)
fun users(): UserPage {...
А в схеме GraphQL у вас будет это:
type UserPage {
number: Int!
size: Int!
content: [User]!
}
type Query {
users: UserPage
}
да, спасибо, необходимо обновить java-инструменты graphql до 5.4.1 и kotlin до 1.3.0
Можете поделиться выводом ошибок из логов?