I'm trying to set up the Spring Kotlin server with graphql-kotlin for the graphql, but it seems configuring the coRouter doesn't work (all routes return 404), which prevents the graphql to create all the routes.
I've tried changing the Spring version, graphql-kotlin version and adding/removing multiple libraries.
I'd like the coRouter to work. To test the coRouter I wrote this simple configuration to return string.
I'd appreciate any help
IndexController.kotlin
package com.project.client.general
import org.springframework.context.annotation.Bean
import org.springframework.context.annotation.Configuration
import org.springframework.web.reactive.function.server.bodyValueAndAwait
import org.springframework.web.reactive.function.server.coRouter
@Configuration
class IndexConfig {
@Bean
fun mainRouter() = coRouter {
"/" {
ok().bodyValueAndAwait(getIndex().trimIndent())
}
}
suspend fun getIndex(): String {
return "Welcome to the API!"
}
}
build.gradle.kts
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
plugins {
// id("org.springframework.boot") version "3.0.3"
// id("io.spring.dependency-management") version "1.1.0"
// kotlin("jvm") version "1.7.22"
// kotlin("plugin.spring") version "1.7.22"
// kotlin("plugin.jpa") version "1.7.22"
id("org.springframework.boot") version "2.7.5"
id("io.spring.dependency-management") version "1.0.15.RELEASE"
kotlin("jvm") version "1.6.21"
kotlin("plugin.spring") version "1.6.21"
kotlin("plugin.jpa") version "1.6.21"
}
group = "com.project.client"
version = "0.0.1-SNAPSHOT"
java.sourceCompatibility = JavaVersion.VERSION_17
configurations {
compileOnly {
extendsFrom(configurations.annotationProcessor.get())
}
}
repositories {
mavenCentral()
}
extra["springShellVersion"] = "3.0.0"
dependencies {
// Spring
implementation("org.springframework.boot:spring-boot-starter-actuator")
implementation("org.springframework.boot:spring-boot-starter-web")
implementation("org.hibernate.validator:hibernate-validator:8.0.0.Final")
developmentOnly("org.springframework.boot:spring-boot-devtools")
implementation("org.springframework.boot:spring-boot-starter-validation")
testImplementation("org.springframework.boot:spring-boot-starter-test")
// Webflux
implementation("org.springframework.boot:spring-boot-starter-webflux")
testImplementation("io.projectreactor:reactor-test")
implementation("io.projectreactor.kotlin:reactor-kotlin-extensions")
implementation("io.projectreactor.addons:reactor-extra")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-reactor")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core")
// Jpa + db
implementation("org.flywaydb:flyway-core")
implementation("org.springframework.boot:spring-boot-starter-data-jpa")
// implementation("org.springframework.data:spring-data-r2dbc")
// implementation("io.r2dbc:r2dbc-postgresql")
runtimeOnly("org.postgresql:postgresql")
// GraphQL
implementation("com.expediagroup:graphql-kotlin-spring-server:7.0.0-alpha.3")
implementation("com.expediagroup:graphql-kotlin-hooks-provider:7.0.0-alpha.3")
implementation ("com.graphql-java:graphql-java-extended-scalars:20.0")
// Security
// implementation("org.springframework.boot:spring-boot-starter-oauth2-client")
// implementation("org.springframework.boot:spring-boot-starter-oauth2-resource-server")
// implementation("org.springframework.boot:spring-boot-starter-security")
// testImplementation("org.springframework.security:spring-security-test")
// implementation("com.auth0:auth0-spring-security-api:1.5.3")
// implementation("com.auth0:auth0:2.0.0")
implementation("org.springframework.boot:spring-boot-starter-quartz")
// Email
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
// implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity6")
// implementation("org.thymeleaf.extras:thymeleaf-extras-springsecurity5")
implementation("org.springframework.boot:spring-boot-starter-mail")
// Kotlin
implementation("com.fasterxml.jackson.module:jackson-module-kotlin")
implementation("org.jetbrains.kotlin:kotlin-reflect")
implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8")
compileOnly("org.projectlombok:lombok")
annotationProcessor("org.projectlombok:lombok")
// Logging
runtimeOnly("io.micrometer:micrometer-registry-datadog")
implementation("io.github.oshai:kotlin-logging-jvm:4.0.0-beta-22")
// compileOnly(project(":shared"))
}
dependencyManagement {
imports {
mavenBom("org.springframework.shell:spring-shell-dependencies:${property("springShellVersion")}")
}
}
tasks.withType<KotlinCompile> {
kotlinOptions {
freeCompilerArgs = listOf("-Xjsr305=strict")
jvmTarget = "17"
}
}
tasks.withType<Test> {
useJUnitPlatform()
}
SpringApplication.kotlin
package com.project.client
import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.autoconfigure.domain.EntityScan
import org.springframework.boot.runApplication
import org.springframework.context.ConfigurableApplicationContext
import org.springframework.data.jpa.repository.config.EnableJpaRepositories
import org.springframework.scheduling.annotation.EnableAsync
import org.springframework.scheduling.annotation.EnableScheduling
@SpringBootApplication
@EntityScan
@EnableJpaRepositories
@EnableScheduling
@EnableAsync
class ClientBackendApplication {
companion object {
var context: ConfigurableApplicationContext? = null
}
}
fun main(args: Array<String>) {
ClientBackendApplication.context = runApplication<ClientBackendApplication>(*args)
}
For people struggling with this issue in the future, the culprit was the tomcat server. Only one of the org.springframework.boot:spring-boot-starter-web or org.springframework.boot:spring-boot-starter-webflux can be used at the same time. So disable spring-boot-starter-web :)