All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.auritylab.graphql.kotlin.toolkit.spring.configuration.GraphQLConfiguration.kt Maven / Gradle / Ivy

package com.auritylab.graphql.kotlin.toolkit.spring.configuration

import graphql.GraphQL
import graphql.execution.AsyncExecutionStrategy
import graphql.execution.DataFetcherExceptionHandler
import graphql.execution.ExecutionStrategy
import graphql.execution.instrumentation.ChainedInstrumentation
import graphql.execution.instrumentation.Instrumentation
import graphql.schema.GraphQLSchema
import java.util.Optional
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean
import org.springframework.context.ApplicationContext
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.context.annotation.Import

@Configuration
@Import(SchemaConfiguration::class)
@ConditionalOnMissingBean(GraphQL::class)
class GraphQLConfiguration(
    private val context: ApplicationContext,
    private val schema: GraphQLSchema,
    private val exceptionHandler: Optional
) {
    @Bean
    fun configureGraphQL(): GraphQL {
        val builder = GraphQL.newGraphQL(schema)

        // Build the Instrumentation and register it if found.
        buildInstrumentation()
            ?.also { builder.instrumentation(it) }

        // Build the execution strategy and apply it to the builder.
        buildExecutionStrategy().also {
            builder.queryExecutionStrategy(it)
            builder.mutationExecutionStrategy(it)
        }

        return builder.build()
    }

    /**
     * Will fetch all available instances of [Instrumentation] and join them if needed.
     * This will utilize the [context] to fetch all beans with type [Instrumentation].
     */
    private fun buildInstrumentation(): Instrumentation? {
        // Fetch the beans using the application context.
        val instrumentationBeans = context.getBeansOfType(Instrumentation::class.java)

        val allInstrumentation = mutableListOf()

        // Go through each found instrumentation bean and add it to the list.
        instrumentationBeans.values.forEach {
            // If it's a ChainedInstrumentation we need to add each of them.
            if (it is ChainedInstrumentation)
                allInstrumentation.addAll(it.instrumentations)
            else
                allInstrumentation.add(it)
        }

        return when {
            allInstrumentation.isEmpty() -> null
            allInstrumentation.size == 1 -> allInstrumentation[0]
            else -> ChainedInstrumentation(allInstrumentation)
        }
    }

    /**
     * Will build a [ExecutionStrategy]. By default this will always build a [AsyncExecutionStrategy],
     * optionally with the given [exceptionHandler].
     */
    private fun buildExecutionStrategy(): ExecutionStrategy =
        if (exceptionHandler.isPresent)
            AsyncExecutionStrategy(exceptionHandler.get())
        else
            AsyncExecutionStrategy()
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy