Drakken Saer
Drakken Saer

Reputation: 889

Akka HTTP: Unmarshal to class with generic type parameter

I have the following class

case class PaginatedSearchResult[T : RootJsonFormat](pages: Option[Page], objects: Option[Seq[T]])

object PaginatedSearchResult extends DefaultJsonProtocol {
  implicit val format = jsonFormat2(PaginatedSearchResult.apply)
}

I am attempting to unmarshal it like so:

Unmarshal(response.entity).to[PaginatedSearchResult[T]]

This is the error I get

Error:(15, 59) could not find implicit value for evidence parameter of type spray.json.RootJsonFormat[T]
  implicit val format = jsonFormat2(PaginatedSearchResult.apply)

I am trying to figure out how to get this to unmarshal correctly. Any help would be appreciated, thank you.

Upvotes: 0

Views: 707

Answers (2)

Drakken Saer
Drakken Saer

Reputation: 889

I managed to fix this with the following code:

case class PaginatedSearchResult[T : JsonFormat](pages: Option[Page], objects: Option[Seq[T]])

object PaginatedSearchResult extends DefaultJsonProtocol {
  implicit def format[T : JsonFormat]: RootJsonFormat[PaginatedSearchResult[T]] = jsonFormat2(PaginatedSearchResult.apply[T])
}

Upvotes: 0

Ivan Stanislavciuc
Ivan Stanislavciuc

Reputation: 7275

There are two problems:

When you define jsonFormat2(PaginatedSearchResult.apply), you're missing implicit value of type RootJsonFormat[T] as it is required in your constructor/apply method. Compiler cannot possible know it for any T and gives you error

Error:(15, 59) could not find implicit value for evidence parameter of type spray.json.RootJsonFormat[T]

You can fix it by defining format as a def

implicit def format[T: RootJsonFormat] = jsonFormat2(PaginatedSearchResult.apply)

Second problem is the place where you require the format to be used

Unmarshal(response.entity).to[PaginatedSearchResult[T]]

In this case you have to use a concrete T or have RootJsonFormat[T] available in the implicit scope.

You could do this

def unmarshal[T: RootJsonFormat] = { 
  Unmarshal(response.entity).to[PaginatedSearchResult[T]]
}

And use it as unmarshal[User] if you have a type User for example.

Upvotes: 2

Related Questions