基于circe-core创建AWS API Gateway自定义解码器的技术咨询
解决AWS API Gateway输入的Circe自定义解码器问题
我来帮你搞定这个Circe解码器的问题!AWS API Gateway返回的queryStringParameters和pathParameters字段有个小坑:当没有参数时,它们会返回null而不是空Map,而Circe默认的Map解码器遇到null会直接解码失败。下面是完整的解决方案:
第一步:创建通用的可选Map解码器
先写一个通用的解码器,专门处理这种可能为null或不存在的Map字段,把它们自动转换成空Map:
import io.circe._ import io.circe.Decoder._ // 处理可能为null/不存在的String键值对Map,转为空Map private val optionalStringMapDecoder: Decoder[Map[String, String]] = Decoder.decodeOption(decodeMap[String, String]).map(_.getOrElse(Map.empty))
这个解码器的逻辑很简单:
- 先用
decodeOption尝试把字段解码成Option[Map[String, String]]——如果字段是null或者不存在,Circe会返回None - 再用
getOrElse把None转换成空Map,有值的话就保留原Map
第二步:完成APIGatewayInput的解码器
接下来把这个通用解码器用到你的APIGatewayInput解码逻辑里,同时补全pathParams的解码:
case class APIGatewayInput(body: Result[Body], queryParams: Map[String, String], pathParams: Map[String, String]) object ApiGatewayInput { private val optionalStringMapDecoder: Decoder[Map[String, String]] = Decoder.decodeOption(decodeMap[String, String]).map(_.getOrElse(Map.empty)) implicit val decodeApiGatewayInput: Decoder[APIGatewayInput] = Decoder.instance { c => for { // 假设Result[Body]已经有对应的Decoder实例,如果没有你需要额外实现它 body <- c.get[Result[Body]]("body") // 用自定义解码器处理queryStringParameters queryParams <- c.get[Map[String, String]]("queryStringParameters")(optionalStringMapDecoder) // 同样处理pathParameters pathParams <- c.get[Map[String, String]]("pathParameters")(optionalStringMapDecoder) } yield APIGatewayInput(body, queryParams, pathParams) } }
为什么这么做?
- 用
for-comprehension组合解码操作是Circe推荐的方式,它会自动处理每一步的解码错误,如果任何一步失败,整个解码器会返回对应的错误信息 - 自定义的
optionalStringMapDecoder完美适配AWS API Gateway的字段特性,避免了因为null导致的解码失败
如果你的Result[Body]是自定义的结果类型(比如类似Either[String, Body]),记得要给它实现对应的Decoder实例哦!
内容的提问来源于stack exchange,提问作者vamsiampolu
相关产品推荐
相关产品推荐

