Ktor Tutorial #12: Registration and Login Flow

In the previous tutorial, you added JWT authentication. Users can register, login, and access protected routes. But the implementation was basic. There were no refresh tokens, no password validation, and no logout. In this tutorial, you will build a complete authentication flow. You will add refresh tokens with rotation, strong password validation, email validation, and a logout endpoint that revokes tokens. What We Will Build Here is the complete auth flow: ...

June 7, 2026 · 9 min

Ktor Tutorial #11: JWT Authentication — Securing Your API

Your API works. It has routes, a database, file uploads, and migrations. But anyone can access any endpoint. There is no authentication. In this tutorial, you will add JWT (JSON Web Token) authentication. Users will register, login, get a token, and use that token to access protected routes. How JWT Authentication Works JWT authentication follows this flow: 1. Client sends email + password → POST /api/auth/login 2. Server verifies credentials 3. Server generates a JWT token 4. Server sends token to client 5. Client stores token 6. Client sends token with every request → Authorization: Bearer <token> 7. Server verifies token and processes request The token contains encoded information (claims) about the user. The server can verify the token without a database query. ...

June 7, 2026 · 9 min

Ktor Tutorial #10: Database Migrations with Flyway

In the previous tutorials, we used SchemaUtils.create() to create database tables. This works for development, but it has a big problem: it cannot handle schema changes. What happens when you need to add a column? Rename a table? Change a data type? You cannot just drop the database and recreate it — production data would be lost. This is where database migrations come in. Why Migrations Matter Without migrations, you have these problems: ...

June 6, 2026 · 6 min

Ktor Tutorial #9: File Uploads and Static Files

Most APIs need to handle files. Profile pictures, document uploads, image galleries — file handling is a common requirement. In this tutorial, you will learn how to serve static files, handle file uploads via multipart form data, validate uploads, and protect against common security issues. Serving Static Files Ktor can serve static files from your resources directory or from the filesystem. From Resources Put files in src/main/resources/static/: src/main/resources/static/ ├── index.html ├── style.css └── logo.png Then configure the route: ...

June 6, 2026 · 7 min

Ktor Tutorial #8: Relationships and Advanced Queries

A real application has connected data. Users own notes. Notes have tags. Orders belong to customers. These connections are called relationships. In this tutorial, you will add relationships between tables, write JOIN queries, and build advanced filtering, sorting, and pagination. Types of Relationships Type Example Implementation One-to-Many One user has many notes Foreign key on notes table Many-to-Many Notes have many tags, tags belong to many notes Join table (note_tags) One-to-One One user has one profile Foreign key with unique constraint One-to-Many: Users → Notes A user can have many notes. Each note belongs to one user (or no user). ...

June 6, 2026 · 7 min

Ktor Tutorial #7: CRUD Operations — Building a REST API

We have a database. We have JSON serialization. Now it is time to build a real REST API. In this tutorial, you will build full CRUD (Create, Read, Update, Delete) operations for notes and users. You will learn the repository pattern, proper HTTP status codes, validation, and how to organize a production-ready API. The Repository Pattern In the previous tutorial, we put database queries directly in route handlers. This works for small projects but becomes messy as your API grows. ...

June 5, 2026 · 8 min

Ktor Tutorial #6: Database Setup — Exposed ORM with H2

Our API works, but the data lives in memory. Restart the server and everything is gone. Time to add a real database. In this tutorial, you will connect your Ktor API to a database using Exposed — JetBrains’ SQL library for Kotlin. We will use H2 for development and explain how to switch to PostgreSQL for production. What is Exposed? Exposed is a SQL library made by JetBrains. It gives you two ways to work with databases: ...

June 5, 2026 · 7 min

Ktor Tutorial #5: Serialization — JSON with kotlinx.serialization

In the previous tutorial, we built routes that return plain text. But real APIs use JSON. Clients send JSON requests and expect JSON responses. In this tutorial, you will add JSON serialization to your Ktor API using kotlinx.serialization — the official Kotlin serialization library. What is Content Negotiation? When a client sends a request, it tells the server what format it wants using the Accept header. When it sends data, it uses the Content-Type header. ...

June 5, 2026 · 8 min

Ktor Tutorial #4: Routing — Handling HTTP Requests

Routing is the core of any backend framework. It maps URLs to code that handles requests and sends responses. In this tutorial, you will learn how to define routes in Ktor, handle different HTTP methods, use path and query parameters, group routes, and handle errors properly. How Routing Works in Ktor Every Ktor route has three parts: HTTP method — GET, POST, PUT, DELETE, etc. Path — The URL pattern like /api/users/{id} Handler — The code that runs when a request matches routing { get("/hello") { // method + path call.respondText("Hi") // handler } } When a client sends GET /hello, Ktor finds the matching route and runs the handler. ...

June 4, 2026 · 8 min

Ktor Tutorial #3: Project Setup — Your First Ktor Application

In the previous tutorials, we learned what Ktor is and how it compares to Spring Boot. Now it is time to build a real project. We will set up a proper Ktor application with the right project structure, plugins, error handling, and configuration. This is the foundation for everything we build in this series. Project Structure Here is the project structure we will create: ktor-tutorial/ ├── build.gradle.kts ├── settings.gradle.kts ├── gradle.properties ├── src/ │ ├── main/ │ │ ├── kotlin/ │ │ │ └── com/kemalcodes/ │ │ │ ├── Application.kt │ │ │ └── plugins/ │ │ │ ├── Routing.kt │ │ │ └── StatusPages.kt │ │ └── resources/ │ │ └── logback.xml │ └── test/ │ └── kotlin/ │ └── com/kemalcodes/ │ └── ApplicationTest.kt This follows the standard Kotlin/Gradle layout. Source code goes in src/main/kotlin, resources in src/main/resources, and tests in src/test/kotlin. ...

June 4, 2026 · 7 min