You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Kotlin coRouter配置失效返回404,GraphQL路由无法生成求助

Spring Kotlin集成graphql-kotlin时coRouter路由404问题解决

问题描述

搭建集成graphql-kotlin的Spring Kotlin服务器,coRouter配置完全失效,所有路由返回404,导致GraphQL无法生成对应路由。已尝试更换Spring、graphql-kotlin版本,调整依赖库,甚至编写了简单的coRouter测试路由(返回字符串),仍无法解决。

相关代码

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)
}

解决步骤

1. 移除Servlet栈依赖,启用Reactive栈

你的build.gradle.kts中同时引入了spring-boot-starter-web(Servlet栈)和spring-boot-starter-webflux(Reactive栈)。Spring Boot默认优先使用Servlet栈,导致coRouter(Reactive路由)无法被加载。必须移除spring-boot-starter-web依赖:

// 删除这一行
// implementation("org.springframework.boot:spring-boot-starter-web")

2. 修正coRouter路由DSL语法

当前路由写法未指定HTTP请求方法,属于语法错误。需要明确指定请求方法(比如GET):

@Bean
fun mainRouter() = coRouter {
    GET("/") {
        ok().bodyValueAndAwait(getIndex().trimIndent())
    }
}

3. 更换稳定版graphql-kotlin

你使用的7.0.0-alpha.3是测试版本,存在兼容性风险。针对Spring Boot 2.7.x,建议使用graphql-kotlin 6.x稳定版:

// 替换为稳定版
implementation("com.expediagroup:graphql-kotlin-spring-server:6.4.1")
implementation("com.expediagroup:graphql-kotlin-hooks-provider:6.4.1")

4. 验证依赖版本兼容性

确保hibernate-validator版本与Spring Boot 2.7.x兼容。Spring Boot 2.7.x默认依赖hibernate-validator 6.x,你使用的8.0.0.Final是Jakarta EE 9+版本,与Spring Boot 2.7.x(Jakarta EE 8)不兼容,需要降级:

// 替换为兼容版本
implementation("org.hibernate.validator:hibernate-validator:6.2.5.Final")

5. 确认组件扫描范围

@SpringBootApplication默认扫描当前包(com.project.client)及子包,IndexConfig在com.project.client.general下,属于子包,扫描范围没问题。如果仍有问题,可以显式指定扫描包:

@SpringBootApplication(scanBasePackages = ["com.project.client"])

验证

完成上述修改后,重启服务器,访问http://localhost:8080应该能看到返回的"Welcome to the API!",同时graphql-kotlin的默认路由(如/graphql、/graphiql)也会正常生效。

内容的提问来源于stack exchange,提问作者Bartosz Prządka

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 10:18:14