Introduction aux fonctions serverless en Kotlin et AWS Lambda
L'architecture serverless est devenue la norme pour créer des applications évolutives et économiques. AWS Lambda est l'un des services les plus populaires pour exécuter du code sans gérer de serveurs. Cependant, la plupart des exemples et de la documentation sont orientés vers Java ou Python. Kotlin, en tant que langage moderne pour la JVM, offre une syntaxe concise et une compatibilité totale avec l'écosystème Java, ce qui en fait un excellent choix pour les fonctions Lambda.
Dans cet article, nous allons parcourir le cycle complet : de la configuration du projet au déploiement et à la surveillance. Vous apprendrez à écrire des fonctions serverless efficaces en Kotlin, à traiter les événements d'API Gateway, S3 et DynamoDB, ainsi qu'à optimiser le démarrage à froid.
1. Configuration du projet et dépendances
Pour commencer, créons un projet Gradle avec le support de Kotlin. La dépendance principale est com.amazonaws:aws-lambda-java-core, qui fournit les interfaces pour les handlers.
Étape 1.1 : Structure du build.gradle.kts
plugins { kotlin("jvm") version "1.9.22" id("io.github.microutils:kotlin-logging") version "3.0.5"}
dependencies { implementation("com.amazonaws:aws-lambda-java-core:1.2.2") implementation("com.amazonaws:aws-lambda-java-events:3.11.3") implementation("com.fasterxml.jackson.module:jackson-module-kotlin:2.15.3") implementation("org.slf4j:slf4j-simple:2.0.9")}
tasks.register<Zip>("buildLambda") { from(sourceSets.main.get().output) from(configurations.runtimeClasspath.get().map { if (it.isDirectory) it else zipTree(it) }) into("build/libs") archiveFileName.set("lambda.zip")}Notez la tâche buildLambda — elle crée un JAR « épais » (fat jar) qu'AWS Lambda pourra exécuter. Sans cette étape, le déploiement ne fonctionnera pas.
Étape 1.2 : Fonction handler de base
Créons un fichier Handler.kt avec une fonction très simple qui accepte un Map<String, String> et retourne une chaîne :
import com.amazonaws.services.lambda.runtime.Contextimport com.amazonaws.services.lambda.runtime.RequestHandler
class HelloHandler : RequestHandler<Map<String, String>, String> { override fun handleRequest(input: Map<String, String>, context: Context): String { val name = input["name"] ?: "World" context.logger.log("Processing request for $name") return "Hello, $name!" }}L'interface RequestHandler est paramétrée par deux types : le type des données d'entrée et le type de la valeur de retour. Kotlin permet d'utiliser Map, String, ainsi que n'importe quelle classe de données.
2. Travail avec les événements AWS (API Gateway, S3, DynamoDB)
Les fonctions serverless travaillent rarement de manière isolée. Le plus souvent, elles réagissent aux événements provenant d'autres services AWS. Examinons trois scénarios populaires.
2.1 Traitement des requêtes HTTP via API Gateway
Pour l'intégration avec API Gateway, utilisez la classe APIGatewayProxyRequestEvent de aws-lambda-java-events :
import com.amazonaws.services.lambda.runtime.events.APIGatewayProxyRequestEventimport com.amazonaws.services.lambda.runtime.events.APIGatewayProxyResponseEventimport com.amazonaws.services.lambda.runtime.Contextimport com.amazonaws.services.lambda.runtime.RequestHandler
class ApiHandler : RequestHandler<APIGatewayProxyRequestEvent, APIGatewayProxyResponseEvent> { override fun handleRequest(input: APIGatewayProxyRequestEvent, context: Context): APIGatewayProxyResponseEvent { val body = "Received: ${input.body}" return APIGatewayProxyResponseEvent() .withStatusCode(200) .withBody(body) .withHeaders(mapOf("Content-Type" to "text/plain")) }}Dans cet exemple, nous extrayons le corps de la requête et retournons une réponse HTTP.