Introduction: Why Kotlin and REST API?
\nModern web development is unthinkable without REST API. If you are already familiar with Python and frameworks like Flask or FastAPI, you surely appreciate the simplicity and speed of creating server applications. Kotlin, as a modern language for the JVM, offers no less elegance and conciseness, especially in combination with the Ktor framework.
\nIn this article, we will create a full-fledged REST API in Kotlin in 30 minutes. You will learn how to set up a project, create routes, handle JSON, and run the server. No fluff — just practice.
\nIf you want to expand your technology stack or just try Kotlin for backend development, this guide is for you.
\n\nStep 1: Project Setup and Dependencies
\nTo start, we need a Kotlin project. We will use the Gradle build system (or Maven — your choice). The fastest way is to create a project via the Ktor Project Generator.
\nSelect the following options:
\n- \n
- Build System: Gradle Kotlin DSL \n
- Engine: Netty (or any other) \n
- Plugins: Content Negotiation (JSON), Routing, Status Pages \n
After downloading the archive, unzip it and open it in IntelliJ IDEA or another editor.
\nIf you are creating the project manually, add the following dependencies to build.gradle.kts:
dependencies {\n implementation("io.ktor:ktor-server-core:2.3.0")\n implementation("io.ktor:ktor-server-netty:2.3.0")\n implementation("io.ktor:ktor-server-content-negotiation:2.3.0")\n implementation("io.ktor:ktor-serialization-kotlinx-json:2.3.0")\n implementation("ch.qos.logback:logback-classic:1.4.11")\n}\nNow let's create the Application.kt file — the application entry point.
import io.ktor.server.engine.*\nimport io.ktor.server.netty.*\nimport io.ktor.server.application.*\nimport io.ktor.server.plugins.contentnegotiation.*\nimport io.ktor.serialization.kotlinx.json.*\nimport kotlinx.serialization.json.Json\n\nfun main() {\n embeddedServer(Netty, port = 8080, host = "0.0.0.0") {\n configureSerialization()\n configureRouting()\n }.start(wait = true)\n}\n\nfun Application.configureSerialization() {\n install(ContentNegotiation) {\n json(Json {\n prettyPrint = true\n isLenient = true\n })\n }\n}\nDone! We have a basic setup for working with JSON and a server on port 8080.
\n\nStep 2: Creating the Data Model and Repository
\nFor a REST API, we need data. Let's create a simple User model and a temporary in-memory repository.
\nFirst, define a data class with the @Serializable annotation:
import kotlinx.serialization.Serializable\n\n@Serializable\ndata class User(\n val id: Int,\n val name: String,\n val email: String\n)\nNow create a repository object that will store users:
\nobject UserRepository {\n private val users = mutableListOf(\n User(1, "Ivan Ivanov", "ivan@example.com"),\n User(2, "Maria Petrova", "maria@example.com")\n )\n\n fun getAll(): List<User> = users.toList()\n\n fun getById(id: Int): User? = users.find { it.id == id }\n\n fun add(user: User): User {\n users.add(user)\n return user\n }\n\n fun delete(id: Int): Boolean = users.removeIf { it.id == id }\n}\nThis is a simple solution, but it is perfect for a 30-minute demonstration.
\n\nStep 3: Setting Up Routes (REST endpoints)
\nNow for the most interesting part — let's create endpoints for CRUD operations. Add the Routing.kt file:
import io.ktor.server.routing.*\nimport io.ktor.server.response.*\nimport io.ktor.server.request.*\n\nfun Application.configureRouting() {\n routing {\n route("/api/u