Page class 的 graphql 模式定义应该是什么样的?

What should graphql schema definition for Page class looks like?

所以我在 kotlin 中有这个 class:

@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)
    }
}

我想要用户 return 页面对象的方法,我对 graphql 完全陌生。我试过这样的事情:

type Page {
    number: Int
    size: Int
    numberOfElements: Int
    content: []
    hasContent: Boolean
    isFirst: Boolean
    isLast: Boolean
    hasNext: Boolean
    hasPrevoius: Boolean
    totalPages: Int
    totalElements: Float
}

但是我的 spring 启动应用程序无法启动,我不知道我的 class 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.

在过去几个月中,GraphQL Java 工具对泛型的处理发生了一些变化。您使用的是什么版本?我刚刚在 5.4.1 版本中尝试过它,它似乎可以工作,但在 5.2.4 版本中却没有。我想知道 this 问题的修复是否相关。

如果有帮助,这是我使用的测试材料:

首先,我这样声明了一个 class: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 的泛型类型参数的每种类型声明一个单独的类型,例如UserPageCustomerPage 等。然后在代码中,每一个都需要映射到正确的 Kotlin class,例如Page<User>Page<Customer>。我不知道在没有每个泛型的具体实现的情况下在代码中执行此操作的方法(希望如果可能的话,其他人可以解释如何执行此操作)。如果 GraphQL 类型名称具有相同的名称,则默认情况下会与 Kotlin class 名称结合,或者在使用 SchemaParser.newParser().dictionary(...

构建 Schema 时使用显式提供的映射

因此,如果您愿意为提供给它的每种类型创建泛型 class 的具体子class,您可以这样做:

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
}