Open arabbani opened 5 years ago
Just configure spring data neo4j and reuse the neo4j-driver:
import org.neo4j.driver.v1.AuthTokens
import org.neo4j.driver.v1.Driver
import org.neo4j.driver.v1.GraphDatabase
import org.neo4j.ogm.config.UsernamePasswordCredentials
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
@Configuration
class Neo4jGraphqlConfig {
@Autowired
private val configuration: org.neo4j.ogm.config.Configuration? = null
@Bean(destroyMethod = "close")
fun driver(): Driver {
val credentials = configuration!!.credentials as UsernamePasswordCredentials
return GraphDatabase.driver(configuration.uri,
AuthTokens.basic(credentials.username, credentials.password))
}
}
and
import graphql.language.VariableReference
import graphql.schema.*
import graphql.schema.idl.SchemaParser
import org.apache.commons.io.IOUtils
import org.neo4j.driver.v1.Driver
import org.neo4j.graphql.Cypher
import org.neo4j.graphql.DataFetchingInterceptor
import org.neo4j.graphql.SchemaBuilder
import org.neo4j.graphql.SchemaConfig
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.beans.factory.annotation.Value
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.core.io.Resource
import org.springframework.security.core.Authentication
import java.io.IOException
import java.math.BigDecimal
import java.math.BigInteger
import java.nio.charset.StandardCharsets
@Configuration
class GraphQLConfig {
@Bean
@Throws(IOException::class)
fun neo4jSchema(
@Value("classpath:graphql/neo4j/*.graphql") graphQls: Array<Resource>,
@Autowired(required = false) dataFetchingInterceptor: DataFetchingInterceptor): GraphQLSchema {
val idl = StringBuilder()
for (resource in graphQls) {
resource.inputStream.use { inputStream -> idl.append(IOUtils.toString(inputStream, StandardCharsets.UTF_8)) }
}
val schemaParser = SchemaParser()
val typeDefinitionRegistry = schemaParser.parse(idl.toString())
return SchemaBuilder.buildSchema(typeDefinitionRegistry, SchemaConfig(), dataFetchingInterceptor)
}
@Bean
fun dataFetchingInterceptor(
driver: Driver,
authentication: Authentication
): DataFetchingInterceptor {
return object : DataFetchingInterceptor {
override fun fetchData(env: DataFetchingEnvironment, delegate: DataFetcher<Cypher>): Any? {
val cypher = delegate.get(env)
val params = toBoltValue(cypher.params, env.variables)
return driver.session().writeTransaction<Any> { tx ->
val boltParams = cypher.params.mapValues { toBoltValue(it.value, env.variables) }
val result = tx.run(cypher.query, boltParams)
val key = result.keys().stream().findFirst().orElse(null)
if (isListType(cypher.type)) {
result.list()
.map { record -> record.get(key).asObject() }
} else {
result.list()
.map { record -> record.get(key).asObject() }
.firstOrNull() ?: emptyMap<String, Any>()
}
}
}
}
}
private fun isListType(type: GraphQLType?): Boolean {
if (type is GraphQLList) {
return true
}
return if (type is GraphQLNonNull) {
isListType(type.wrappedType)
} else false
}
fun toBoltValue(value: Any?, params: Map<String, Any?>) = when (value) {
is VariableReference -> params[value.name]
is BigInteger -> value.longValueExact()
is BigDecimal -> value.toDouble()
else -> value
}
}
I'm using
<dependency>
<groupId>io.leangen.graphql</groupId>
<artifactId>graphql-spqr-spring-boot-starter</artifactId>
<version>0.0.5-SNAPSHOT</version>
</dependency>
relates to #119 and #97
How to integrate this library with Spring data