Skip to main content
Version: 5.x.x

Writing Schemas with Spring

In order to expose your queries, mutations, and subscriptions in the GraphQL schema create beans that implement the corresponding marker interface and they will be automatically picked up by graphql-kotlin-spring-server auto-configuration library.

data class Widget(val id: ID, val value: String)
@Componentclass WidgetQuery : Query {  fun widget(id: ID): Widget = getWidgetFromDB(id)}
@Componentclass WidgetMutation : Mutation {  fun updateWidget(id: ID, value: String): Boolean = updateWidgetInDB(id, value)}
@Componentclass WidgetSubscription : Subscription {  fun widgetChanges(id: ID): Publisher<Widget> = getPublisherOfUpdates(id)}

will result in a Spring Boot reactive GraphQL web application with following schema.

schema {  query: Query  mutation: Mutation  subscription: Subscription}
type Widget {    id: ID!    value: String!}
type Query {  widget(id: ID!): Widget!}
type Mutation {    updateWidget(id: ID!, value: String!): Boolean!}
type Subscription {    widgetChanges(id: ID!): Widget!}

Spring Beans#

Since the top level objects are Spring components, Spring will automatically autowire dependent beans as normal. Refer to Spring Documentation for details.

@Componentclass WidgetQuery(private val repository: WidgetRepository) : Query {    fun getWidget(id: Int): Widget = repository.findWidget(id)}

Spring Beans in Arguments#

graphql-kotlin-spring-server provides Spring-aware data fetcher that automatically autowires Spring beans when they are specified as function arguments. @Autowired arguments should be explicitly excluded from the GraphQL schema by also specifying @GraphQLIgnore.

@Componentclass SpringQuery : Query {    fun getWidget(@GraphQLIgnore @Autowired repository: WidgetRepository, id: Int): Widget = repository.findWidget(id)}

If you are using custom data fetcher make sure that you extend SpringDataFetcher instead of the base FunctionDataFetcher to keep this functionallity.

We have examples of these techniques implemented in Spring boot in the example app.