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

Ktor Tutorial #2: Ktor vs Spring Boot — Which Kotlin Backend?

You decided to build a backend with Kotlin. Good choice. But now you face another decision: Ktor or Spring Boot? Both are great frameworks. Both support Kotlin. But they are very different in philosophy, design, and use cases. Let’s compare them honestly. The Big Picture Ktor is a lightweight, modular framework built by JetBrains. It is Kotlin-native, coroutine-based, and you add features as plugins. Spring Boot is a full-featured, batteries-included framework from VMware (now Broadcom). It started as a Java framework and added Kotlin support later. ...

June 4, 2026 · 7 min

Ktor Tutorial #1: What is Ktor? — Kotlin's Modern Backend Framework

You know Kotlin. You build Android apps, maybe KMP apps. But what about the backend? Every app needs a server. An API to fetch data from. A backend to store users, handle payments, send notifications. You could learn Node.js and Express. Or Python and FastAPI. Or Java and Spring Boot. Or you could use the Kotlin you already know — and build your backend with Ktor. What is Ktor? Ktor is a backend framework built by JetBrains — the same company that created Kotlin. It lets you build web servers, REST APIs, microservices, and web applications using Kotlin. ...

June 3, 2026 · 7 min

Security for Developers #14: Security Checklist — Complete Guide

This is the final article in the Security for Developers series. It brings everything together into a single, actionable checklist you can use for every project. Bookmark this page and review it whenever you start a new project or prepare for a security review. How to Use This Checklist Each item is marked with a priority level: P0 (Critical): Do this before going to production. Skipping it means you are vulnerable. P1 (High): Do this within the first week of production. Important for security posture. P2 (Medium): Do this within the first month. Improves defense in depth. P3 (Low): Nice to have. Do when you have time. Authentication Checklist # Item Priority Details 1 Hash passwords with bcrypt or Argon2 P0 Never store plaintext. Use cost factor 12+ for bcrypt. 2 Enforce minimum password length of 8 characters P0 NIST recommends 8+ characters. Do not require special characters. 3 Use HTTPS for all authentication endpoints P0 Credentials in transit must be encrypted. 4 Implement account lockout after failed attempts P1 Lock after 5-10 failed attempts for 15-30 minutes. 5 Use JWT with short expiration (15-60 min) P1 Combine with refresh tokens for longer sessions. 6 Sign JWTs with RS256 or EdDSA (not HS256 for distributed) P1 Asymmetric signing prevents key sharing. 7 Store tokens in httpOnly cookies (not localStorage) P1 Prevents XSS from stealing tokens. 8 Implement refresh token rotation P1 Invalidate old refresh token on each use. 9 Validate JWT signature and expiration on every request P0 Never trust a token without validation. 10 Support multi-factor authentication (MFA) P2 TOTP or WebAuthn. SMS is better than nothing. 11 Check passwords against breached lists (Have I Been Pwned) P2 Reject passwords that appear in known breaches. 12 Log all authentication events P1 Successful and failed logins, password changes. Reference: Tutorial #2: Authentication ...

June 3, 2026 · 8 min

Security for Developers #13: Container and Docker Security

In the previous tutorial, you learned about security logging and monitoring. Now let us secure where your code runs. Docker containers are everywhere, but the default configuration is not secure enough for production. In this article, you will learn how to harden Docker containers, scan images for vulnerabilities, and manage secrets safely. Why Container Security Matters Containers provide isolation, but they are not virtual machines. By default: Containers run as root — if an attacker breaks out, they have root on the host Docker images contain hundreds of packages, many with known vulnerabilities Secrets are often baked into images or passed as environment variables (visible in process lists) Network ports are exposed by default — more attack surface A compromised container can lead to: ...

June 3, 2026 · 7 min