Publicité

Dig Deeper With http4s

CTO & Co-Founder at Knoldus Software à Knoldus Inc.
10 Mar 2023
Publicité

Contenu connexe

Publicité

Dig Deeper With http4s

  1. Presented By: Swantika Gupta Dig Deeper With http4s
  2. Lack of etiquette and manners is a huge turn off. KnolX Etiquettes Punctuality Join the session 5 minutes prior to the session start time. We start on time and conclude on time! Feedback Make sure to submit a constructive feedback for all sessions as it is very helpful for the presenter. Silent Mode Keep your mobile devices in silent mode, feel free to move out of session in case you need to attend an urgent call. Avoid Disturbance Avoid unwanted chit chat during the session.
  3. Our Agenda Recap of http4s Introducing Middleware in http4s Demo with Basic http4s Routes Demo with http4s Routes + middleware
  4. Basics of http4s type HttpRoutes = Kleisli [ OptionT [ F, * ], Request, Response ] http4s - Recap ● Lightweight Library ● Typeful ● Purely Functional ● Based on Cats and fs2-streaming ● Streaming ● Performant Heart of http4s
  5. http4s DSL object LocalDateVar { def unapply(str: String): Option[LocalDate] = { if (!str.isEmpty) Try(LocalDate.parse(str)).toOption else None } } case GET -> Root / "weather" / "temperature" / LocalDateVar(localDate) => Ok(getTemperatureForecast(localDate) .map(s"The temperature on $localDate will be: " + _)) http4s - Recap val route: HttpRoutes[IO] = HttpRoutes.of[IO] { case GET -> Root / "length" / str => Ok(str.length.toString) case GET -> Root / "hello" / name => Ok(s"""Hello, ${name}!""") } Handling Path Parameters
  6. QueryParamDecoderMatcher object OptionalYearQueryParamMatcher extends OptionalQueryParamDecoderMatcher[Year]("year") val routes = HttpRoutes.of[IO] { case GET -> Root / "temperature" :? OptionalYearQueryParamMatcher(maybeYear) => maybeYear match { case None => Ok(getAverageTemperatureForCurrentYear) case Some(year) => Ok(getAverageTemperatureForYear(year)) } } Ex: /temperature or /temperature?year=2005 http4s - Recap implicit val yearQueryParamDecoder: QueryParamDecoder[Year] = QueryParamDecoder[Int].map(Year.of) object YearQueryParamMatcher extends QueryParamDecoderMatcher[Year]("year") case GET -> Root / "weather" / "temperature" :? YearQueryParamMatcher(year) => Ok(getAverageTemperatureForYear(year) .map(s"Average temperature for $country in $year was: " + _)) Ex: /weather/temperature?year=2005 OptionalQueryParamDecoderMatcher
  7. ValidatingQueryParamDecoderMatcher object LongParamMatcher extends OptionalValidatingQueryParamDecoderMatcher[Long]("long") case GET -> Root / "number" :? LongParamMatcher(maybeNumber) => maybeNumber match { case Some(n) => n.fold( parseFailures => BadRequest("unable to parse argument 'long'"), year => Ok(n.toString) ) case None => BadRequest("missing number") } Ex: /number?long=13 http4s - Recap implicit val yearQueryParamDecoder = QueryParamDecoder[Int] .emap(i => Try(Year.of(i)) .toEither .leftMap(t => ParseFailure(t.getMessage, t.getMessage))) object YearQueryParamMatcher extends ValidatingQueryParamDecoderMatcher[Year]("year") case GET -> Root / "temperature" :? YearQueryParamMatcher(yearValidated) => yearValidated.fold( parseFailures => BadRequest("unable to parse argument year"), year => Ok(getAverageTemperatureForYear(year)) ) Ex: /temperature?year=2005 OptionalValidatingQueryParamDecoderMatcher
  8. http4s Server def healthCheck(client: Client[IO]): IO[String] = client.expect[String](s"$baseUri/healthcheck") EmberClientBuilder.default[IO].build .use { client => healthCheck(client).unsafeRunSync() } http4s - Recap EmberServerBuilder .default[IO] .withHost(Host.fromString(host).get) .withPort(Port.fromInt(port).get) .withHttpApp(new HttpService().combinedRoutes) .build .use(_ => IO.never) .as(ExitCode.Success) http4s Client
  9. Demo with http4s Routes
  10. ● Abstraction around a service ● Manipulate the request sent to a service and/or response returned by the service ● Function that takes one service and returns another service ● Ex: def addHeaders( service: HttpRoutes[IO], header: Header.ToRaw ): HttpRoutes[IO] addHeaders( userServiceAPI, "extra-added-header" -> "extra-header-value" ) http4s - Middleware http4s includes some middleware OOB in the codebase: ● Authentication ● CORS ● Response Compression ● Metrics ● Loggers
  11. Demo with http4s Routes and Middleware
  12. Thank You ! Get in touch with us: Scala Studio, Knoldus
Publicité