You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

47 lines
1.3 KiB

3 years ago
  1. package wow.doge.http4sdemo
  2. import cats.Applicative
  3. import cats.effect.Sync
  4. import cats.implicits._
  5. import io.circe.Decoder
  6. import io.circe.Encoder
  7. import io.circe.generic.semiauto._
  8. import monix.bio.Task
  9. import org.http4s.Method._
  10. import org.http4s._
  11. import org.http4s.circe._
  12. import org.http4s.client.Client
  13. import org.http4s.client.dsl.Http4sClientDsl
  14. import org.http4s.implicits._
  15. sealed trait Jokes[F[_]] {
  16. def get: F[Jokes.Joke]
  17. }
  18. object Jokes {
  19. def apply[F[_]](implicit ev: Jokes[F]): Jokes[F] = ev
  20. final case class Joke(joke: String)
  21. object Joke {
  22. implicit val jokeDecoder: Decoder[Joke] = deriveDecoder[Joke]
  23. implicit def jokeEntityDecoder[F[_]: Sync]: EntityDecoder[F, Joke] =
  24. jsonOf
  25. implicit val jokeEncoder: Encoder[Joke] = deriveEncoder[Joke]
  26. implicit def jokeEntityEncoder[F[_]: Applicative]: EntityEncoder[F, Joke] =
  27. jsonEncoderOf
  28. }
  29. final case class JokeError(e: Throwable) extends RuntimeException
  30. def impl(C: Client[Task]): Jokes[Task] = new Jokes[Task] {
  31. val dsl = new Http4sClientDsl[Task] {}
  32. import dsl._
  33. def get: Task[Jokes.Joke] = {
  34. C.expect[Joke](GET(uri"https://icanhazdadjoke.com/"))
  35. .adaptError { case t =>
  36. JokeError(t)
  37. } // Prevent Client Json Decoding Failure Leaking
  38. }
  39. }
  40. }