48 lines
1.3 KiB
Scala
48 lines
1.3 KiB
Scala
package wow.doge.http4sdemo
|
|
|
|
import cats.Applicative
|
|
import cats.effect.Sync
|
|
import cats.implicits._
|
|
import io.circe.Decoder
|
|
import io.circe.Encoder
|
|
import io.circe.generic.semiauto._
|
|
import monix.bio.Task
|
|
import org.http4s.Method._
|
|
import org.http4s._
|
|
import org.http4s.circe._
|
|
import org.http4s.client.Client
|
|
import org.http4s.client.dsl.Http4sClientDsl
|
|
import org.http4s.implicits._
|
|
|
|
sealed trait Jokes[F[_]] {
|
|
def get: F[Jokes.Joke]
|
|
}
|
|
|
|
object Jokes {
|
|
def apply[F[_]](implicit ev: Jokes[F]): Jokes[F] = ev
|
|
|
|
final case class Joke(joke: String)
|
|
object Joke {
|
|
implicit val jokeDecoder: Decoder[Joke] = deriveDecoder[Joke]
|
|
implicit def jokeEntityDecoder[F[_]: Sync]: EntityDecoder[F, Joke] =
|
|
jsonOf
|
|
implicit val jokeEncoder: Encoder[Joke] = deriveEncoder[Joke]
|
|
implicit def jokeEntityEncoder[F[_]: Applicative]: EntityEncoder[F, Joke] =
|
|
jsonEncoderOf
|
|
}
|
|
|
|
final case class JokeError(e: Throwable) extends RuntimeException
|
|
|
|
def impl(C: Client[Task]): Jokes[Task] = new Jokes[Task] {
|
|
val dsl = new Http4sClientDsl[Task] {}
|
|
import dsl._
|
|
def get: Task[Jokes.Joke] = {
|
|
C.expect[Joke](GET(uri"https://icanhazdadjoke.com/"))
|
|
.adaptError { case t =>
|
|
JokeError(t)
|
|
} // Prevent Client Json Decoding Failure Leaking
|
|
}
|
|
}
|
|
|
|
}
|