2017-01-27 2 views
4

J'essaie d'utiliser http4s, circe et http4s-circe. Ci-dessous j'essaie d'utiliser la fonction de dérivation automatique de circe.Encodeurs et décodeurs Circe avec Http4s

import org.http4s.client.blaze.SimpleHttp1Client 
import org.http4s.Status.ResponseClass.Successful 
import io.circe.syntax._ 
import org.http4s._ 
import org.http4s.headers._ 
import org.http4s.circe._ 
import scalaz.concurrent.Task 
import io.circe._ 

final case class Login(username: String, password: String) 
final case class Token(token: String) 

object JsonHelpers { 
    import io.circe.generic.auto._ 
    implicit val loginEntityEncoder : EntityEncoder[Login] = jsonEncoderOf[Login] 
    implicit val loginEntityDecoder : EntityDecoder[Login] = jsonOf[Login] 
    implicit val tokenEntityEncoder: EntityEncoder[Token] = jsonEncoderOf[Token] 
    implicit val tokenEntityDecoder : EntityDecoder[Token] = jsonOf[Token] 
} 

object Http4sTest2 extends App { 
    import JsonHelpers._ 
    val url = "http://" 
    val uri = Uri.fromString(url).valueOr(throw _) 
    val list = List[Header](`Content-Type`(MediaType.`application/json`), `Accept`(MediaType.`application/json`)) 
    val request = Request(uri = uri, method = Method.POST) 
     .withBody(Login("foo", "bar").asJson) 
     .map{r => r.replaceAllHeaders(list :_*)}.run 
    val client = SimpleHttp1Client() 
    val result = client.fetch[Option[Token]](request){ 
     case Successful(response) => response.as[Token].map(Some(_)) 
     case _ => Task(Option.empty[Token]) 
    }.run 
    println(result) 
} 

Je reçois plusieurs instances de ces deux erreurs du compilateur

Error:scalac: missing or invalid dependency detected while loading class file 'GenericInstances.class'. 
Could not access type Secondary in object io.circe.Encoder, 
because it (or its dependencies) are missing. Check your build definition for 
missing or conflicting dependencies. (Re-run with `-Ylog-classpath` to see the problematic classpath.) 
A full rebuild may help if 'GenericInstances.class' was compiled against an incompatible version of io.circe.Encoder. 


Error:(25, 74) could not find implicit value for parameter encoder: io.circe.Encoder[Login] 
    implicit val loginEntityEncoder : EntityEncoder[Login] = jsonEncoderOf[Login] 
+2

Je ne connais pas terriblement avec les décisions de conception dans http4s, mais je suppose qu'il est intentionnel qu'il ne fournisse que des instances 'EntityEncoder' pour' io.circe.Json', pas n'importe quoi avec une instance 'io.circe.Encoder'. Dans votre cas, vous pouvez ignorer les huit instances explicitement définies en utilisant la dérivation générique de circe et en appelant 'asJson' sur' Login' dans 'withBody'. –

Répondre

4

j'ai pu résoudre ce problème. J'ai fait une recherche sur google sur la dépendance de circe de sbt et j'ai copié collé le premier résultat de recherche. c'était environ 0,1 et c'est pourquoi les choses ne fonctionnaient pas pour moi.

j'ai changé mes dépendances à

libraryDependencies ++= Seq(
    "org.http4s" %% "http4s-core" % http4sVersion, 
    "org.http4s" %% "http4s-dsl" % http4sVersion, 
    "org.http4s" %% "http4s-blaze-client" % http4sVersion, 
    "org.http4s" %% "http4s-circe" % http4sVersion, 
    "io.circe" %% "circe-core" % "0.7.0", 
    "io.circe" %% "circe-generic" % "0.7.0" 
) 

et dérivation maintenant automatique fonctionne très bien et je suis en mesure de compiler le code ci-dessous

import org.http4s.client.blaze.SimpleHttp1Client 
import org.http4s._ 
import org.http4s.headers._ 
import org.http4s.circe._ 

import scalaz.concurrent.Task 
import io.circe.syntax._ 
import io.circe.generic.auto._ 
import org.http4s.Status.ResponseClass.Successful 

case class Login(username: String, password: String) 
case class Token(token: String) 

object JsonHelpers { 
    implicit val loginEntityEncoder : EntityEncoder[Login] = jsonEncoderOf[Login] 
    implicit val loginEntityDecoder : EntityDecoder[Login] = jsonOf[Login] 
    implicit val tokenEntityEncoder: EntityEncoder[Token] = jsonEncoderOf[Token] 
    implicit val tokenEntityDecoder : EntityDecoder[Token] = jsonOf[Token] 
} 

object Http4sTest2 extends App { 
    import JsonHelpers._ 
    val url = "http://" 
    val uri = Uri.fromString(url).valueOr(throw _) 
    val list = List[Header](`Content-Type`(MediaType.`application/json`), `Accept`(MediaType.`application/json`)) 
    val request = Request(uri = uri, method = Method.POST) 
     .withBody(Login("foo", "bar").asJson) 
     .map{r => r.replaceAllHeaders(list :_*)}.run 
    val client = SimpleHttp1Client() 
    val result = client.fetch[Option[Token]](request){ 
     case Successful(response) => response.as[Token].map(Some(_)) 
     case _ => Task(Option.empty[Token]) 
    }.run 
    println(result) 
}