I want to create a CRUD API using Micronaut and deploy it on AWS Lambda, exposing the different methods with Amazon API Gateway. I could create different Kotlin Projects per endpoint (GET, POST...), one including one function, but that's kind of cumbersome so I'd rather have a single project with all the CRUD functions.
My current application contains two functions: one Supplier (GET) and one Consumer (POST).
Application:
object Application {
@JvmStatic
fun main(args: Array<String>) {
Micronaut.build()
.packages("micronaut.aws.poc")
.mainClass(Application.javaClass)
.start()
}
}
Supplier:
@FunctionBean("micronaut-aws-poc")
class MicronautAwsPocFunction : Supplier<String> {
override fun get(): String {
println("GET")
return "micronaut-aws-poc"
}
}
Consumer:
@FunctionBean("micronaut-aws-poc-post")
class MicronautAwsPocPostFunction : Consumer<String> {
override fun accept(t: String) {
println("POST $t")
}
}
Then, I have created a resource in Amazon API Gateway with one GET and one POST method. The problem is, no matter which one I call, the MicronautAwsPocFunction is always invoked.
I tried a different approach, this is how I solved it:
Instead of using functions I changed to Lambda Functions Using AWS API Gateway Proxy. Also take into account this specific aws lambda documentation.
I recreated the project with this command mn create-app micronaut-poc --features aws-api-gateway -l kotlin
Now I have a "normal" REST application with two controllers:
@Controller("/")
class PingController {
@Get("/")
fun index(): String {
return "{\"pong\":true}"
}
}
@Controller("/")
class PongController {
@Post("/")
fun post(): String {
println("PONG!!!!!!!")
return "{\"ping\":true}"
}
}
The magic happens in the AWS API Gateway configuration. We have to configure a proxy resource:
Finally we can invoke the lambda from the API Gateway setting the correct HTTP Method. IMPORTANT: Set a host header, otherwise Micronaut will throw a nullpointerexception:
GET:
POST: