
Anatomy of the Lambda function when used in Lambda proxy integration
In Lambda integration, because the Lambda function and the API are decoupled, the Lambda function handler can implement the RequestHandler<INPUT,OUTPUT> interface with INPUT and OUTPUT being any types that are transformed and sent by the API Gateway. In fact, the Lambda function that we saw in the previous section is a valid candidate as a Lambda function for Lambda integration.
For Lambda proxy integration, since INPUT and OUTPUT conform to a particular format, the handler function needs to respect that.
In the case of Lambda proxy integration, the handler function is as follows:
.class Handler : RequestHandler<Map<String, Any>, ApiGatewayResponse> {
override fun handleRequest(input: Map<String, Any>, context: Context): ApiGatewayResponse {
//Do the work
return ApiGatewayResponse.build {
statusCode = 200
objectBody = Response()
}
}
}
Such a handler takes in a map of String keys and Any values, and returns the output in the form of ApiGatewayResponse.
API gatewayResponse is a type that helps build out an integration response from the Lambda function, which can be processed by the API Gateway. We saw the sample payload in the previous section.
The definition of this class is as follows:
import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import org.apache.logging.log4j.LogManager
import org.apache.logging.log4j.Logger
import java.nio.charset.StandardCharsets
import java.util.*
class ApiGatewayResponse(
val statusCode: Int = 200,
var body: String? = null,
val headers: Map<String, String>? = Collections.emptyMap(),
val isBase64Encoded: Boolean = false
) {
companion object {
inline fun build(block: Builder.() -> Unit) = Builder().apply(block).build()
}
class Builder {
var LOG: Logger = LogManager.getLogger(Builder::class.java)
var objectMapper: ObjectMapper = ObjectMapper()
var statusCode: Int = 200
var rawBody: String? = null
var headers: Map<String, String>? = Collections.emptyMap()
var objectBody: Response? = null
var binaryBody: ByteArray? = null
var base64Encoded: Boolean = false
fun build(): ApiGatewayResponse {
var body: String? = null
if (rawBody != null) {
body = rawBody as String
}
else if (objectBody != null) {
try {
body = objectMapper.writeValueAsString(objectBody)
} catch (e: JsonProcessingException) {
LOG.error("failed to serialize object", e)
throw RuntimeException(e)
}
} else if (binaryBody != null) {
body = String(Base64.getEncoder().encode(binaryBody), StandardCharsets.UTF_8)
}
return ApiGatewayResponse(statusCode, body, headers, base64Encoded)
}
}
}
Now that we have seen the types of integrations of Lambda with API Gateway, let's proceed with integrating the Lambda function that we created with an API Gateway. Please note that this is of the type Lambda integration and not Lambda proxy integration.