-
Notifications
You must be signed in to change notification settings - Fork 4
GraphQL Java Kickstart support
NOTE: GraphQL Java Kickstart is not supported since release 4.0.0
Kobby is focused on client-side development but provides little support of server-side GraphQL Java Kickstart library. You can generate resolver interfaces by GraphQL schema by means of Kobby Plugin.
Put your GraphQL schema file in the project resources with graphqls
extension. For example, let
define cinema.graphqls
schema file:
type Query {
countries(offset: Int! = 0, limit: Int! = 100): [Country!]!
}
type Country {
id: ID!
name: String!
films(offset: Int! = 0, limit: Int! = 100): [Film!]!
}
type Film {
id: ID!
title: String!
country: Country!
}
Add Kobby plugin to your build.gradle.kts
, to generate Kotlin DSL (Maven plugin is also available):
repositories {
mavenLocal()
mavenCentral()
}
buildscript {
repositories {
mavenLocal()
mavenCentral()
}
}
plugins {
kotlin("jvm") version "1.5.21"
id("io.github.ermadmi78.kobby") version "1.0.0"
}
dependencies {
// Add this dependency to enable graphql-java-kickstart resolvers generation by Kobby
compileOnly("com.graphql-java-kickstart:graphql-java-tools:11.0.1")
// Add this dependency to wrap subscription resolver functions result in org.reactivestreams.Publisher
compileOnly("org.reactivestreams:reactive-streams:1.0.3")
}
Run gradle clean build
, and Kobby will generate resolver interfaces and DTO classes for you:
import graphql.kickstart.tools.GraphQLQueryResolver
import graphql.kickstart.tools.GraphQLResolver
interface CinemaQueryResolver : GraphQLQueryResolver {
suspend fun countries(offset: Int, limit: Int): List<CountryDto>
}
interface CinemaCountryResolver : GraphQLResolver<CountryDto> {
suspend fun films(
country: CountryDto,
offset: Int,
limit: Int
): List<FilmDto>
}
data class CountryDto(
val id: Long? = null,
val name: String? = null,
val films: List<FilmDto>? = null
)
data class FilmDto(
val id: Long? = null,
val title: String? = null,
val country: CountryDto? = null
)
Kobby generates resolver functions for all fields in root GraphQL types (Query
, Mutation
and Subscription
). For
other GraphQL types, Kobby generates resolver functions only for fields with arguments.
For example, for the Country
type, Kobby generates the CinemaCountryResolver
interface with one films
method, but
for the Film
type, it does not generate a resolver at all.
But sometimes we have to resolve fields without arguments. For example, we have to resolve the country
field in
the Film
type. You can ask Kobby to generate a resolver for this field using the @resolve
directive. Let's modify
our schema:
directive @resolve on FIELD_DEFINITION
type Query {
countries(offset: Int! = 0, limit: Int! = 100): [Country!]!
}
type Country {
id: ID!
name: String!
films(offset: Int! = 0, limit: Int! = 100): [Film!]!
}
type Film {
id: ID!
title: String!
country: Country! @resolve
}
And Kobby will generate resolver interface for the Film
type:
import graphql.kickstart.tools.GraphQLResolver
interface CinemaFilmResolver : GraphQLResolver<FilmDto> {
suspend fun country(film: FilmDto): CountryDto
}
Together with the resolver interfaces, Kobby generates the client DSL. If you don't need it, you can disable client
generation by means of kobby
extension:
plugins {
kotlin("jvm") version "1.5.21"
id("io.github.ermadmi78.kobby") version "1.0.0"
}
kobby {
kotlin {
dto {
graphQL {
// Disable helper DTO classes generation
enabled = false
}
}
entity {
// Disable entities generation
enabled = false
}
}
}
The kobby
extension also provides additional settings for resolver generation:
kobby {
kotlin {
// Configuration of resolver interfaces generation
resolver {
// Is resolver interfaces generation enabled
// By default `true` if `com.graphql-java-kickstart:graphql-java-tools`
// artifact is in the project dependencies
enabled = null // Boolean
// Is wrap subscription resolver functions result in `org.reactivestreams.Publisher`
// By default `true` if `org.reactivestreams:reactive-streams`
// artifact is in the project dependencies
publisherEnabled = null // Boolean
// Package name for resolver interfaces relative to root package name
packageName = "resolver"
// Prefix for resolver interfaces
// By default is capitalized context name
prefix = null // String
// Postfix for resolver interfaces
postfix = "Resolver"
// Name for parent object argument
// By default is de-capitalized name of parent object type
argument = null // String
// If not null, Kobby will generate default implementation for
// functions in resolver interfaces that looks like:
// TODO("$toDoMessage")
toDoMessage = null // String
}
}
}