Dariusz Kuc
11/05/2019, 3:20 PMgraphql-kotlin
library. Post today highlights how graphql-kotlin-schema-generator
can be used to generate your GraphQL schemas directly from your source code - https://medium.com/expedia-group-tech/creating-graphql-schemas-in-kotlin-aaaac0ab0672
Stay tuned for the next posts in the series that will highlight federation and spring server modules!Stephan Schroeder
11/06/2019, 9:47 AMprivate inline fun <reified O, A:Any> dataFetcherByArgument(
argumentName: String,
crossinline transform: (A)->O
): DataFetcher<O> = DataFetcher<O>
{ dataFetchingEnvironment ->
val argument: A = dataFetchingEnvironment.getArgument(argumentName)
transform(argument)
}
private inline fun <reified O, S:Any> dataFetcherBySource(
crossinline transform: (S)->O
): DataFetcher<O> = DataFetcher<O> { dataFetchingEnvironment ->
val source: S = dataFetchingEnvironment.getSource()
transform(source)
}
private fun RuntimeWiring.Builder.addTypeWiring(graphQLType: String, fieldName: String, dataFetcher: DataFetcher<*>) {
this.type(newTypeWiring(graphQLType).dataFetcher(fieldName, dataFetcher))
}
with that explicit configuration is pretty straight forward and takes up less space
@Configuration
class GraphQLProvider(
val offerService: OfferService,
val offerDetailService: OfferDetailService
) {
@Bean
fun graphQL(): GraphQL {
val sdl = ClassPathResource("schema.graphqls").inputStream.reader().readText()
val graphQLSchema = SchemaGenerator().makeExecutableSchema(
SchemaParser().parse(sdl),
buildWiring()
)
return GraphQL.newGraphQL(graphQLSchema).build()
}
private fun buildWiring(): RuntimeWiring = RuntimeWiring.newRuntimeWiring().apply {
addTypeWiring("Query", "status", DataFetcher<String> { "up and running" })
addTypeWiring("Query", "offerById", dataFetcherByArgument( "offerId" ) {argument: String ->
offerService.getOfferBy(argument.toLong())
})
addTypeWiring("Offer", "offerDetail", dataFetcherBySource { offer: Offer ->
offerDetailService.getOfferDetailBy(offer.offerDetailId)
})
}.build()
}
The formating looks better when not crammed into a discussion-collumn 😅Dariusz Kuc
11/06/2019, 1:09 PMgraphql-kotlin
you would simply create
class MyQueries(private val offerService: OfferService) {
val status = "up and running"
fun offerById(id: String) = offerService.getOfferBy(id.toLong())
}
class Offer(val offerDetailId: Long, private val offerDetailService: OfferDetailService) {
fun offerDetail() = offerDetailService.getOfferDetailBy(offerDetailId)
}
Stephan Schroeder
11/06/2019, 2:26 PMDariusz Kuc
11/06/2019, 3:07 PMclass Book(val authors: List<Author>)
class Author(val books: List<Book>)
Stephan Schroeder
11/07/2019, 10:57 AMDariusz Kuc
11/07/2019, 2:30 PMAuthor
that return Book
which has a function to return list of Author
, so you could represent your circular dependencies (but also to be completely honest I'm unsure how useful those are, guess it really depends on your data set)apollo-android
is a generic client and its only android
specific in its name, it can be easily used on the server side. Also that linked is correct -> JS is currently still the primary environment, your options are fairly limited outside of JS ecosystem. I'd personally go with apollo-android
as it will give you type safety but you could do even a simple POST. I know some people that also used https://github.com/americanexpress/nodes but personally not a big fan of it.