kotlin-graphql默认只支持基本的几个类型,需添加其他类型的支持,只能通过配置Hooks。
异常
若未配置,启动时会报异常。以下代码是因为对象中有LocalDateTime
,schema无法进行解析,因此报错。
Invocation of init method failed; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.expediagroup.graphql.spring.RoutesConfiguration': Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'schema' defined in class path resource [com/expediagroup/graphql/spring/SchemaAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [graphql.schema.GraphQLSchema]: Factory method 'schema' threw exception; nested exception is com.expediagroup.graphql.exceptions.TypeNotSupportedException: Cannot convert java.time.LocalDateTime since it is not a valid GraphQL type or outside the supported packages "[com.xxxx.xx]"
对此报错,官网也给出了解释。
![](https://img.haomeiwen.com/i24476144/0e0f8fbd83ac030b.png)
解决
- CustomerTypeHooks
import com.expediagroup.graphql.hooks.SchemaGeneratorHooks
import graphql.language.StringValue
import graphql.schema.Coercing
import graphql.schema.GraphQLScalarType
import graphql.schema.GraphQLType
import java.time.LocalDateTime
import java.time.format.DateTimeFormatter
import kotlin.reflect.KType
/**
* @Author: anson
* @Date: 2020/8/17 1:18 PM
*/
class CustomerTypeHooks : SchemaGeneratorHooks {
override fun willGenerateGraphQLType(type: KType): GraphQLType? = when (type.classifier) {
LocalDateTime::class -> graphqlDateType
else -> null
}
}
internal val graphqlDateType = GraphQLScalarType.newScalar()
.name("Date")
.description("A type representing a formatted java.time.LocalDateTime")
.coercing(InstantCoercing)
.build()
private object InstantCoercing : Coercing<LocalDateTime, String> {
private val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
override fun parseValue(input: Any?): LocalDateTime {
val timeString = formatter.parse(serialize(input))
return LocalDateTime.from(timeString)
}
override fun parseLiteral(input: Any?): LocalDateTime? {
val timeString = (input as? StringValue)?.value
return LocalDateTime.from(formatter.parse(timeString))
}
override fun serialize(dataFetcherResult: Any?): String = dataFetcherResult.toString()
}
- 配置到Spring启动类
import com.***.CustomerTypeHooks
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication
import org.springframework.context.annotation.Bean
@SpringBootApplication
class GrahpqlApplication {
@Bean
fun hooks() = CustomerTypeHooks()
}
fun main(args: Array<String>) {
runApplication<GrahpqlApplication>(*args)
}
网友评论