kotlinvalidationhttpserverktorrequest-validation

Ktor-server RequestValidation not working


I am using ktor (2.1.0) to create a small API. While doing so, I am trying to leverage Ktor-server cool functionalities, including RequestValidation.

That being said, it is not working and I can't figure out why since it looks to me very close to the examples in the documentation.

This is my server config:

embeddedServer(Netty, port = 8080) {

    routing {
        post("/stock") {
           val dto = call.receive<CreateStockRequest>()
            call.respond(HttpStatusCode.NoContent)
        }
    }

    install(ContentNegotiation) {
        json(Json {
            prettyPrint = true
            isLenient = true
        })
    }

    install(StatusPages) {
        exception<RequestValidationException> { call, cause ->
            call.respond(HttpStatusCode.BadRequest, cause.reasons.joinToString())
        }
    }

    install(RequestValidation) {
        validate<CreateStockRequest> { request ->
            if (request.name.isBlank())
                ValidationResult.Invalid("Stock must have a name")

            if (request.symbol.isBlank())
                ValidationResult.Invalid("Symbol must have a name")

            ValidationResult.Valid
        }
    }
}

This is the request object being "received":

@Serializable
data class CreateStockRequest(val name: String, val symbol: String)

And this is the body being sent:

{
    "name": "",
    "symbol": "something"
}

I was expecting to get a BadRequest response, but I am getting a NoContent response as if everything was fine with the request.

Am I doing something wrong?


Solution

  • In your example, the server responds with BadRequest only if both "name" and "symbol" are blank. You can replace your validation logic with the when expression:

    validate<CreateStockRequest> { request ->
        when {
            request.name.isBlank() -> ValidationResult.Invalid("Stock must have a name")
            request.symbol.isBlank() -> ValidationResult.Invalid("Symbol must have a name")
            else -> ValidationResult.Valid
        }
    }