Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

518
Vistas
Ktor: How can I validate JSON request?

I already know how to receive a JSON object and automatically deserialize it into the required format (e.g. with a data class). Also look here: How to receive JSON object in Ktor?

My problem now is that I want to validate the JSON request and return BadRequest if it's not in the desired format, something like that in Django: https://stackoverflow.com/a/44085405/5005715

How can I do that in Ktor/Kotlin? Unfortunately, I couldn't find a solution in the docs. Also, required/optional fields would be nice.

over 4 years ago · Santiago Trujillo
3 Respuestas
Responde la pregunta

0

You can use hibernate-validator for input validations. Refer below:

Add Dependency (Gradle):

compile "org.hibernate.validator:hibernate-validator:6.1.1.Final"

Annotate your data class (DTO):

data class SampleDto(
    @field:Min(value=100)
    val id: Int,
    @field:Max(value=99)
    val age: Int
)

Add Validator in Routing:

import javax.validation.Validation

fun Application.module() {

    val service = SampleService()
    val validator = Validation.buildDefaultValidatorFactory().validator

    routing {
        post("/sample/resource/") {
            val sampleDto = call.receive<SampleDto>()
            sampleDto.validate(validator)
            service.process(sampleDto)
            call.respond(HttpStatusCode.OK)
        }
    }
}

@Throws(BadRequestException::class)
fun <T : Any> T.validate(validator: Validator) {
    validator.validate(this)
        .takeIf { it.isNotEmpty() }
        ?.let { throw BadRequestException(it.first().messageWithFieldName()) }
}

fun <T : Any> ConstraintViolation<T>.messageWithFieldName() = "${this.propertyPath} ${this.message}"

Bonus Step (Optional) - Add Exception Handler:

fun Application.exceptionHandler() {

    install(StatusPages) {
        exception<BadRequestException> { e ->
            call.respond(HttpStatusCode.BadRequest, ErrorDto(e.message, HttpStatusCode.BadRequest.value))
            throw e
        }
    }

}

data class ErrorDto(val message: String, val errorCode: Int)
over 4 years ago · Santiago Trujillo Denunciar

0

Here is a quick example of how to validate and respond with 400 if needed.

fun main(args: Array<String>) {
    embeddedServer(Netty, 5000) {
        install(CallLogging)
        install(ContentNegotiation) { gson { } }
        install(Routing) {
            post("test") {
                val sample = call.receive<Sample>()
                if (!sample.validate()) {
                    call.respond(HttpStatusCode.BadRequest, "Sample did not pass validation")
                }
                call.respond("Ok")
            }
        }
    }.start()
}

fun Sample.validate(): Boolean = id > 5

data class Sample(val id: Int)

Did you have something else in mind?

There are no inbuilt annotations or the like.

over 4 years ago · Santiago Trujillo Denunciar

0

Taking the answer of Andreas a step further you can return a list of errors when the request is invalid like so:

    post {
        val postDog = call.receive<PostDog>()
        val validationErrors = postDog.validate()
        if (validationErrors.isEmpty()) {

            // Save to database

        } else {
            call.respond(HttpStatusCode.BadRequest, validationErrors)
        }

    }

    fun PostDog.validate() : List<Error> {
        var validationErrors : MutableList<Error> = mutableListOf()
        if(name == null || name.isBlank())
            validationErrors.add(Error(code = "dog.name.required", message = "Dog requires a name"))
        if(color == null || color.isBlank())
            validationErrors.add(Error(code = "dog.color.required", message = "Dog requires a color"))            
        return validationErrors
    }

    data class PostDog(
      val name: String,
      val color: String          
    )

    data class Error(
        val code : String,
        val message : String
    )
over 4 years ago · Santiago Trujillo Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda