Kotlinx.serialization and Valiktor: Data Validation in Kotlin

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Data Validation in Kotlin: Kotlinx.serialization and Valiktor Libraries

Data validation is a critical part of Kotlin development, especially when creating REST APIs, working with forms, or processing incoming JSON requests. Unlike Python, where Pydantic or Marshmallow are popular, the Kotlin ecosystem is led by Kotlinx.serialization (for serialization) and Valiktor (for declarative validation). These libraries allow you to check data correctness at compile time and runtime, minimizing errors.

Why is validation needed?

Without validation, an application can accept incorrect data: empty strings, negative values, emails without "@". This leads to databases with garbage, 500 errors, and vulnerabilities. In Kotlin, typing helps but does not save you from business rules (e.g., "age from 18 to 120"). Validation libraries allow you to describe rules declaratively and reuse them.

How to install?

For Kotlinx.serialization, add to build.gradle.kts:

plugins {    kotlin("plugin.serialization") version "1.9.22"}dependencies {    implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.2")}

For Valiktor (pure validation):

dependencies {    implementation("org.valiktor:valiktor-core:0.12.0")}

Main features

  • Kotlinx.serialization: annotations @Serializable, @Required, @Range for basic field checking during JSON deserialization.
  • Valiktor: functions validate, constraint, custom validators, support for nested objects and collections.
  • Both libraries work with Kotlin data class and do not require reflection.

Code example in Kotlin

A simple example with Kotlinx.serialization + Valiktor:

import kotlinx.serialization.*import org.valiktor.functions.*import org.valiktor.validate

@Serializabledata class User( @Required val name: String, @Range(from = 18, to = 120) val age: Int, val email: String)

fun main() { val user = User("Alice", 25, "alice@example.com") // Validation via Valiktor validate(user) { validate(User::name).isNotEmpty() validate(User::age).isGreaterThanOrEqualTo(18) validate(User::email).matches(Regex("^[\\\\w.-]+@[\\\\w.-]+\\\\.\\\\w{2,}$")) } println("User $user passed validation")}

If the data is incorrect, Valiktor throws an exception with an error description.

When to use?

  • API input data: checking the request body in Ktor or Spring Boot.
  • Forms: in Android or web applications.
  • Configurations: validation of properties files at application startup.

Use Kotlinx.serialization for basic serialization/deserialization, and Valiktor for complex business rules (e.g., checking that the start date is less than the end date).

Recommendations