I am trying to write a thin Scala wrapper around the Java Aws Lambda Client.
This class should accept 2 generic parameters:
- An input type A - which should be either a case class, which gets serialized to Json and sent to the Lambda function, OR Nothing/Unit type, in case the Lambda function intended to be called doesn't take any input parameters.
- An input type B - which should be a case class which is the actual deserialized Json->case class that the Lambda function returned, OR Unit in case the Lambda function doesn't return anything.
Something along the lines of:
import com.amazonaws.services.lambda.model.InvokeRequest
import com.amazonaws.services.lambda.{AWSLambda, AWSLambdaClientBuilder}
import org.json4s.native.Serialization
import org.json4s.native.Serialization.{read, write}
class LambdaInvoker[A <: AnyRef, B <: AnyRef](val client: AWSLambda = AWSLambdaClientBuilder.defaultClient()) {
implicit val serialization: Serialization.type = org.json4s.native.Serialization
def call(input: A, function: String): B = {
val request = new InvokeRequest().withFunctionName(function).withPayload(write(input))
val result = client.invoke(request)
val rawJsonResponse = new String(result.getPayload.array(), "UTF-8")
read(rawJsonResponse)
}
}
This works fine when I have both input and outputs to the call, but can't figure out what's the best "Scala" way of dealing with when A or B should not be present. I was looking for ways of getting the runtime type of A or B, checking against Unit, then base the logic on that, but couldn't find an obvious way (probably due to type erasure?)
If there is a different pattern I can apply here, without generic types but with Optionals, or anything else which achieves the same thing, that's also great.
class LambdaInvoker[A : Encoder, B : Decoder]
. – Luis Miguel Mejía SuárezUnit
is a subtype ofAnyVal
, not ofAnyRef
. – Dmytro Mitin