CODESAMPLE

Microservices - Kotlin

Share on:

The Microservices pattern structures an application as a collection of loosely coupled, independently deployable services, modeled around a business domain. Each service owns its data and communicates via lightweight mechanisms, often an HTTP REST API. This example demonstrates a simplified scenario with two microservices: customer-service and product-service. Kotlin’s concise syntax and support for both OOP and functional programming make it well-suited for building these services. We use Ktor, a Kotlin-native framework, for creating lightweight REST APIs. Data classes and immutability are favored for data transfer objects, aligning with functional principles and simplifying communication.

// customer-service/src/main/kotlin/CustomerService.kt
package customer

import io.ktor.application.*
import io.ktor.response.*
import io.ktor.routing.*
import kotlinx.serialization.Serializable

data class Customer(val id: Int, val name: String)

fun main(args: Array<String>): Unit {
    val customers = listOf(Customer(1, "Alice"), Customer(2, "Bob"))

    io.ktor.server.netty.EngineMain.main(args)
}

fun Application.module() {
    install(io.ktor.serialization.Serialization)
    routing {
        get("/customers/{id}") {
            val id = call.parameters["id"]?.toIntOrNull() ?: return@get call.respond(
                io.ktor.http.HttpStatusCode.BadRequest,
                "Invalid customer ID"
            )
            val customer = customers.find { it.id == id }
            if (customer != null) {
                call.respond(customer)
            } else {
                call.respond(io.ktor.http.HttpStatusCode.NotFound, "Customer not found")
            }
        }
    }
}

// product-service/src/main/kotlin/ProductService.kt
package product

import io.ktor.application.*
import io.ktor.response.*
import io.ktor.routing.*
import kotlinx.serialization.Serializable

data class Product(val id: Int, val name: String, val price: Double)

fun main(args: Array<String>): Unit {
    val products = listOf(Product(1, "Laptop", 1200.0), Product(2, "Mouse", 25.0))

    io.ktor.server.netty.EngineMain.main(args)
}

fun Application.module() {
    install(io.ktor.serialization.Serialization)
    routing {
        get("/products/{id}") {
            val id = call.parameters["id"]?.toIntOrNull() ?: return@get call.respond(
                io.ktor.http.HttpStatusCode.BadRequest,
                "Invalid product ID"
            )
            val product = products.find { it.id == id }
            if (product != null) {
                call.respond(product)
            } else {
                call.respond(io.ktor.http.HttpStatusCode.NotFound, "Product not found")
            }
        }
    }
}