in http-server/src/main/scala/com/twitter/finatra/http/internal/routing/CallbackConverter.scala [115:176]
private def createResponseCallback[RequestType: TypeTag, ResponseType: TypeTag](
requestCallback: Request => ResponseType
): Request => Future[Response] = {
val manifestResponseType = TypeUtils.asManifest[ResponseType]
manifestResponseType match {
case futureResponse if futureResponse == manifest[Future[Response]] =>
requestCallback.asInstanceOf[Request => Future[Response]]
case futureOption if isFutureOption(futureOption) =>
// we special-case in order to convert None --> 404 NotFound
request: Request =>
requestCallback(request)
.asInstanceOf[Future[Option[_]]].map(optionToHttpResponse(request))
case response if response == manifest[Response] =>
request: Request => Future(requestCallback(request).asInstanceOf[Response])
case future if runtimeClassEqs[Future[_]](future) =>
request: Request =>
requestCallback(request).asInstanceOf[Future[_]].map(createHttpResponse(request))
case scalaFuture if runtimeClassEqs[ScalaFuture[_]](scalaFuture) =>
scalaFutureTypes(requestCallback)(manifestResponseType)
case option if runtimeClassEqs[Option[_]](option) =>
request: Request =>
Future(optionToHttpResponse(request)(requestCallback(request).asInstanceOf[Option[_]]))
case string if runtimeClassEqs[String](string) =>
// optimized
request: Request =>
Future.value(
createHttpResponseWithContent(
status = Status.Ok,
content = Buf.Utf8(requestCallback(request).asInstanceOf[String]),
contentType = responseBuilder.plainTextContentType
)
)
case stringMap if isStringMap(stringMap) =>
// optimized
request: Request =>
Future.value(
createHttpResponseWithContent(
status = Status.Ok,
content = mapper
.writeStringMapAsBuf(requestCallback(request).asInstanceOf[Map[String, String]]),
contentType = responseBuilder.jsonContentType
)
)
case map if runtimeClassEqs[Map[_, _]](map) =>
// optimized
request: Request =>
val response = Response(Version.Http11, Status.Ok)
response.content = mapper.writeValueAsBuf(requestCallback(request))
response.headerMap.addUnsafe(Fields.ContentType, responseBuilder.jsonContentType)
Future.value(response)
case streamingType if isStreamingType(streamingType) =>
streamingTypes[RequestType, ResponseType](requestCallback, streamingType)
case _ =>
request: Request =>
requestCallback(request) match {
case throwable: Throwable => Future.exception(throwable)
case futureResult: Future[_] => futureResult.map(createHttpResponse(request))
case result => Future(createHttpResponse(request)(result))
}
}
}