SlideShare une entreprise Scribd logo
1  sur  20
Télécharger pour lire hors ligne
Presented By: Swantika Gupta
Hands-On With
http4s
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.
Agenda
Introduction to http4s
http4s DSL
http4s Streaming Nature
http4s Support for Circe
Request -
Response
Model
Creating
Endpoint
Creating
Server
Matching
Requests
Sending
RAW
JSON
Extracting
Requests
Receiving
RAW
JSON
EntityBody[
F]
http4s - What makes it different?
Define
Values
Light-weight
Product
Quality
Typeful
Pure
Functional
Performant
Streaming
Cross -
Platform
http4s - Request and Response
type HttpRoutes = Kleisli[OptionT[F, *], Request, Response],
Request -> Response
Request -> Option[Response]
Request -> F[Option[Response]]
Kleisli[OptionT[F, *], Request, Response]
http4s DSL
Defining a simple endpoint
implicit val runtime: IORuntime = cats.effect.unsafe.IORuntime.global
val route: HttpRoutes[IO] = HttpRoutes.of[IO] {
case GET -> Root / "length" / str => Ok(str.length.toString)
}
Request Type Endpoint Behavior
GET (/POST/PUT) /length/{str} str.length.toString
http4s DSL
Running a Server
BlazeServerBuilder[IO]
.bindHttp(8080, "localhost")
.withHttpApp(app)
.resource
.useForever
.as(ExitCode.Success)
val app =
Router(
“/” -> route,
“/api” -> servicesAPI
)
.orNotFound
http4s DSL
Matching & Extracting Requests
HttpRoutes.of[IO] {
case GET -> Root / "hello" / name => Ok(s"Hello, ${name}!")
}
HttpRoutes.of[IO] {
case GET -> "hello" /: rest => Ok(s"""Hello, ${rest.segments.mkString(" and ")}!""")
}
HttpRoutes.of[IO] {
case GET -> Root / file ~ "json" => Ok(s"""{"response": "You asked for $file"}""")
}
● The -> Object and Matching Paths
http4s DSL
Matching & Extracting Requests
def getUserName(userId: Int): IO[String] = ???
val usersService = HttpRoutes.of[IO] {
case GET -> Root / "users" / IntVar(userId) =>
Ok(getUserName(userId))
}
object LocalDateVar {
def unapply(str: String): Option[LocalDate] = {
if (!str.isEmpty)
Try(LocalDate.parse(str)).toOption
else
None
}
}
def getTemperatureForecast(date: LocalDate): IO[Double] =
IO(42.23)
val dailyWeatherService = HttpRoutes.of[IO] {
case GET -> Root / "weather" / "temperature" /
LocalDateVar(localDate) =>
Ok(getTemperatureForecast(localDate)
.map(s"The temperature on $localDate will be: " +
_))
}
// /weather/temperature/2016-11-05
● Handling Path Parameters
object FullNameAndIDExtractor extends MatrixVar("name", List("first", "last", "id"))
val greetingWithIdService = HttpRoutes.of[IO] {
case GET -> Root / "hello" / FullNameAndIDExtractor(first, last, IntVar(id)) / "greeting" =>
Ok(s"Hello, $first $last. Your User ID is $id.")
}
// /hello/name;first=john;last=doe;id=123/greeting
● Handling Matrix Path Parameters
http4s DSL
Matching & Extracting Requests
object CountryQueryParamMatcher extends QueryParamDecoderMatcher[String]("country")
implicit val yearQueryParamDecoder: QueryParamDecoder[Year] =
QueryParamDecoder[Int].map(Year.of)
object YearQueryParamMatcher extends QueryParamDecoderMatcher[Year]("year")
val averageTemperatureService = HttpRoutes.of[IO] {
case GET -> Root / "weather" / "temperature" :? CountryQueryParamMatcher(country) +& YearQueryParamMatcher(year) =>
Ok(getAverageTemperatureForCountryAndYear(country, year)
.map(s"Average temperature for $country in $year was: " + _))
}
● Handling Query Parameters - QueryParamDecoderMatcher
http4s DSL
Matching & Extracting Requests
implicit val yearQueryParamDecoder: QueryParamDecoder[Year] = QueryParamDecoder[Int].map(Year.of)
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))
}
}
● Handling Query Parameters - OptionalQueryParamDecoderMatcher
http4s DSL
Matching & Extracting Requests
implicit val yearQueryParamDecoder: QueryParamDecoder[Year] = QueryParamDecoder[Int]
.emap(i => Try(Year.of(i))
.toEither
.leftMap(t =>
ParseFailure(t.getMessage, t.getMessage)
)
)
object YearQueryParamMatcher extends ValidatingQueryParamDecoderMatcher[Year]("year")
val routes = HttpRoutes.of[IO] {
case GET -> Root / "temperature" :? YearQueryParamMatcher(yearValidated) =>
yearValidated.fold(
parseFailures => BadRequest("unable to parse argument year"),
year => Ok(getAverageTemperatureForYear(year))
)
}
● Handling Query Parameters - ValidatingQueryParamDecoderMatcher
http4s DSL
Matching & Extracting Requests
object LongParamMatcher extends OptionalValidatingQueryParamDecoderMatcher[Long]("long")
val routes = HttpRoutes.of[IO] {
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")
}
}
● Handling Query Parameters - OptionalValidatingQueryParamDecoderMatcher
http4s DSL
Matching & Extracting Requests
http4s Streaming Nature
Request[F] / R esponse[F]
EntityBody[F]
Stream[F, Byte]
EntityEncoder / EntityDecoder
Raw Data
Types:
String, File,
InputStream
JSON
Support:
curve,
json4s-native
XML
Support:
scala-xml
http4s JSON Codec - Circe
import io.circe.syntax._
case class Hello(name: String)
implicit val HelloEncoder: Encoder[Hello] =
Encoder.instance { (hello: Hello) =>
json"""{"hello": ${hello.name}}"""
}
Hello("Alice").asJson
// res3: Json = JObject(value = object[hello -> "Alice"])
import io.circe.generic.auto._
case class User(name: String)
User("Alice").asJson
// res4: Json = JObject(value = object[name -> "Alice"])
Ok(Hello("Alice").asJson).unsafeRunSync()
POST(User("Bob").asJson, uri"/hello")
● Sending Raw JSON
http4s JSON Codec - Circe
Ok("""{"name":"Alice"}""").flatMap(_.as[Json]).unsafeRunS
ync()
// res8: Json = JObject(value = object[name -> "Alice"])
POST("""{"name":"Bob"}""",
uri"/hello").as[Json].unsafeRunSync()
// res9: Json = JObject(value = object[name -> "Bob"])
case class User(name: String)
implicit val userDecoder = jsonOf[IO, User]
Ok("""{"name":"Alice"}""").flatMap(_.as[User]).unsafeRunS
ync()
// res10: User = User(name = "Alice")
POST("""{"name":"Bob"}""",
uri"/hello").as[User].unsafeRunSync()
// res11: User = User(name = "Bob")
● Receiving Raw JSON
http4s JSON Codec - Circe
// Server
import io.circe.generic.auto._
case class User(name: String)
case class Hello(greeting: String)
implicit val decoder = jsonOf[IO, User]
val jsonApp = HttpRoutes.of[IO] {
case req @ POST -> Root / "hello" =>
for {
user <- req.as[User] // Decode
resp <- Ok(Hello(user.name).asJson) // Encode
} yield (resp)
}.orNotFound
● Combining Encoder and Decoder
// Client
import io.circe.generic.auto._
def helloClient(name: String): IO[Hello] = {
val req = POST(User(name).asJson,
uri"http://localhost:8080/hello")
EmberClientBuilder.default[IO].build.use {
httpClient =>
httpClient.expect(req)(jsonOf[IO, Hello])
}
}
helloClient("Alice").unsafeRunSync()
Demo
Thank You !
Get in touch with us:
Scala Studio, Knoldus

Contenu connexe

Tendances

Tendances (20)

Fiware IoT_IDAS_intro_ul20_v2
Fiware IoT_IDAS_intro_ul20_v2Fiware IoT_IDAS_intro_ul20_v2
Fiware IoT_IDAS_intro_ul20_v2
 
Role Based Access Controls (RBAC) for SSH and Kubernetes Access with Teleport
Role Based Access Controls (RBAC) for SSH and Kubernetes Access with TeleportRole Based Access Controls (RBAC) for SSH and Kubernetes Access with Teleport
Role Based Access Controls (RBAC) for SSH and Kubernetes Access with Teleport
 
Grafana introduction
Grafana introductionGrafana introduction
Grafana introduction
 
Docker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting TechniquesDocker Networking - Common Issues and Troubleshooting Techniques
Docker Networking - Common Issues and Troubleshooting Techniques
 
Crystal Hirschorn_Building Internal Developer Platforms that will make the en...
Crystal Hirschorn_Building Internal Developer Platforms that will make the en...Crystal Hirschorn_Building Internal Developer Platforms that will make the en...
Crystal Hirschorn_Building Internal Developer Platforms that will make the en...
 
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...How to test infrastructure code: automated testing for Terraform, Kubernetes,...
How to test infrastructure code: automated testing for Terraform, Kubernetes,...
 
An Introduction to Prometheus (GrafanaCon 2016)
An Introduction to Prometheus (GrafanaCon 2016)An Introduction to Prometheus (GrafanaCon 2016)
An Introduction to Prometheus (GrafanaCon 2016)
 
Terraform Best Practices - DevOps Unicorns 2019
Terraform Best Practices - DevOps Unicorns 2019Terraform Best Practices - DevOps Unicorns 2019
Terraform Best Practices - DevOps Unicorns 2019
 
初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準初探 OpenTelemetry - 蒐集遙測數據的新標準
初探 OpenTelemetry - 蒐集遙測數據的新標準
 
How to monitor your micro-service with Prometheus?
How to monitor your micro-service with Prometheus?How to monitor your micro-service with Prometheus?
How to monitor your micro-service with Prometheus?
 
Introduction to kubernetes
Introduction to kubernetesIntroduction to kubernetes
Introduction to kubernetes
 
stupid-simple-kubernetes-final.pdf
stupid-simple-kubernetes-final.pdfstupid-simple-kubernetes-final.pdf
stupid-simple-kubernetes-final.pdf
 
Autoscaling on Kubernetes
Autoscaling on KubernetesAutoscaling on Kubernetes
Autoscaling on Kubernetes
 
Terraform on Azure
Terraform on AzureTerraform on Azure
Terraform on Azure
 
Cloud Monitoring tool Grafana
Cloud Monitoring  tool Grafana Cloud Monitoring  tool Grafana
Cloud Monitoring tool Grafana
 
Istio Service Mesh for Developers and Platform Engineers
Istio Service Mesh for Developers and Platform EngineersIstio Service Mesh for Developers and Platform Engineers
Istio Service Mesh for Developers and Platform Engineers
 
Grafana.pptx
Grafana.pptxGrafana.pptx
Grafana.pptx
 
Virtual training Intro to InfluxDB & Telegraf
Virtual training  Intro to InfluxDB & TelegrafVirtual training  Intro to InfluxDB & Telegraf
Virtual training Intro to InfluxDB & Telegraf
 
Infrastructure & System Monitoring using Prometheus
Infrastructure & System Monitoring using PrometheusInfrastructure & System Monitoring using Prometheus
Infrastructure & System Monitoring using Prometheus
 
Server monitoring using grafana and prometheus
Server monitoring using grafana and prometheusServer monitoring using grafana and prometheus
Server monitoring using grafana and prometheus
 

Similaire à Http4s

To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2
Bahul Neel Upadhyaya
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
Tom Croucher
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
elliando dias
 
FBTFTP: an opensource framework to build dynamic tftp servers
FBTFTP: an opensource framework to build dynamic tftp serversFBTFTP: an opensource framework to build dynamic tftp servers
FBTFTP: an opensource framework to build dynamic tftp servers
Angelo Failla
 

Similaire à Http4s (20)

Dig Deeper With http4s
Dig Deeper With http4sDig Deeper With http4s
Dig Deeper With http4s
 
Intro to Node
Intro to NodeIntro to Node
Intro to Node
 
SwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup GroupSwampDragon presentation: The Copenhagen Django Meetup Group
SwampDragon presentation: The Copenhagen Django Meetup Group
 
Finch + Finagle OAuth2
Finch + Finagle OAuth2Finch + Finagle OAuth2
Finch + Finagle OAuth2
 
To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2To Infinity & Beyond: Protocols & sequences in Node - Part 2
To Infinity & Beyond: Protocols & sequences in Node - Part 2
 
Solr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene EuroconSolr @ Etsy - Apache Lucene Eurocon
Solr @ Etsy - Apache Lucene Eurocon
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
 
Protocol-Oriented Networking
Protocol-Oriented NetworkingProtocol-Oriented Networking
Protocol-Oriented Networking
 
A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...A language for the Internet: Why JavaScript and Node.js is right for Internet...
A language for the Internet: Why JavaScript and Node.js is right for Internet...
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
Net/http and the http.handler interface
Net/http and the http.handler interfaceNet/http and the http.handler interface
Net/http and the http.handler interface
 
Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)Azure Durable Functions (2019-04-27)
Azure Durable Functions (2019-04-27)
 
Beyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js TransactionsBeyond Profilers: Tracing Node.js Transactions
Beyond Profilers: Tracing Node.js Transactions
 
REST made simple with Java
REST made simple with JavaREST made simple with Java
REST made simple with Java
 
iPhone and Rails integration
iPhone and Rails integrationiPhone and Rails integration
iPhone and Rails integration
 
The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016The Road To Reactive with RxJava JEEConf 2016
The Road To Reactive with RxJava JEEConf 2016
 
FBTFTP: an opensource framework to build dynamic tftp servers
FBTFTP: an opensource framework to build dynamic tftp serversFBTFTP: an opensource framework to build dynamic tftp servers
FBTFTP: an opensource framework to build dynamic tftp servers
 
Android dev 3
Android dev 3Android dev 3
Android dev 3
 
Reitit - Clojure/North 2019
Reitit - Clojure/North 2019Reitit - Clojure/North 2019
Reitit - Clojure/North 2019
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 

Plus de Knoldus Inc.

Plus de Knoldus Inc. (20)

Authentication in Svelte using cookies.pptx
Authentication in Svelte using cookies.pptxAuthentication in Svelte using cookies.pptx
Authentication in Svelte using cookies.pptx
 
OAuth2 Implementation Presentation (Java)
OAuth2 Implementation Presentation (Java)OAuth2 Implementation Presentation (Java)
OAuth2 Implementation Presentation (Java)
 
Supply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptxSupply chain security with Kubeclarity.pptx
Supply chain security with Kubeclarity.pptx
 
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML ParsingMastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
Mastering Web Scraping with JSoup Unlocking the Secrets of HTML Parsing
 
Akka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On IntroductionAkka gRPC Essentials A Hands-On Introduction
Akka gRPC Essentials A Hands-On Introduction
 
Entity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptxEntity Core with Core Microservices.pptx
Entity Core with Core Microservices.pptx
 
Introduction to Redis and its features.pptx
Introduction to Redis and its features.pptxIntroduction to Redis and its features.pptx
Introduction to Redis and its features.pptx
 
GraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdfGraphQL with .NET Core Microservices.pdf
GraphQL with .NET Core Microservices.pdf
 
NuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptxNuGet Packages Presentation (DoT NeT).pptx
NuGet Packages Presentation (DoT NeT).pptx
 
Data Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable TestingData Quality in Test Automation Navigating the Path to Reliable Testing
Data Quality in Test Automation Navigating the Path to Reliable Testing
 
K8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose KubernetesK8sGPTThe AI​ way to diagnose Kubernetes
K8sGPTThe AI​ way to diagnose Kubernetes
 
Introduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptxIntroduction to Circle Ci Presentation.pptx
Introduction to Circle Ci Presentation.pptx
 
Robusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptxRobusta -Tool Presentation (DevOps).pptx
Robusta -Tool Presentation (DevOps).pptx
 
Optimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptxOptimizing Kubernetes using GOLDILOCKS.pptx
Optimizing Kubernetes using GOLDILOCKS.pptx
 
Azure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptxAzure Function App Exception Handling.pptx
Azure Function App Exception Handling.pptx
 
CQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptxCQRS Design Pattern Presentation (Java).pptx
CQRS Design Pattern Presentation (Java).pptx
 
ETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake PresentationETL Observability: Azure to Snowflake Presentation
ETL Observability: Azure to Snowflake Presentation
 
Scripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics PresentationScripting with K6 - Beyond the Basics Presentation
Scripting with K6 - Beyond the Basics Presentation
 
Getting started with dotnet core Web APIs
Getting started with dotnet core Web APIsGetting started with dotnet core Web APIs
Getting started with dotnet core Web APIs
 
Introduction To Rust part II Presentation
Introduction To Rust part II PresentationIntroduction To Rust part II Presentation
Introduction To Rust part II Presentation
 

Dernier

Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
WSO2
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Safe Software
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Victor Rentea
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Victor Rentea
 

Dernier (20)

FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024FWD Group - Insurer Innovation Award 2024
FWD Group - Insurer Innovation Award 2024
 
DBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor PresentationDBX First Quarter 2024 Investor Presentation
DBX First Quarter 2024 Investor Presentation
 
Architecting Cloud Native Applications
Architecting Cloud Native ApplicationsArchitecting Cloud Native Applications
Architecting Cloud Native Applications
 
Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)Introduction to Multilingual Retrieval Augmented Generation (RAG)
Introduction to Multilingual Retrieval Augmented Generation (RAG)
 
Six Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal OntologySix Myths about Ontologies: The Basics of Formal Ontology
Six Myths about Ontologies: The Basics of Formal Ontology
 
[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf[BuildWithAI] Introduction to Gemini.pdf
[BuildWithAI] Introduction to Gemini.pdf
 
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data DiscoveryTrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
TrustArc Webinar - Unlock the Power of AI-Driven Data Discovery
 
CNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In PakistanCNIC Information System with Pakdata Cf In Pakistan
CNIC Information System with Pakdata Cf In Pakistan
 
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers:  A Deep Dive into Serverless Spatial Data and FMECloud Frontiers:  A Deep Dive into Serverless Spatial Data and FME
Cloud Frontiers: A Deep Dive into Serverless Spatial Data and FME
 
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemkeProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
ProductAnonymous-April2024-WinProductDiscovery-MelissaKlemke
 
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot ModelMcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
Mcleodganj Call Girls 🥰 8617370543 Service Offer VIP Hot Model
 
WSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering DevelopersWSO2's API Vision: Unifying Control, Empowering Developers
WSO2's API Vision: Unifying Control, Empowering Developers
 
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 AmsterdamDEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
DEV meet-up UiPath Document Understanding May 7 2024 Amsterdam
 
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
Modular Monolith - a Practical Alternative to Microservices @ Devoxx UK 2024
 
How to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected WorkerHow to Troubleshoot Apps for the Modern Connected Worker
How to Troubleshoot Apps for the Modern Connected Worker
 
Artificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : UncertaintyArtificial Intelligence Chap.5 : Uncertainty
Artificial Intelligence Chap.5 : Uncertainty
 
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
Apidays New York 2024 - The Good, the Bad and the Governed by David O'Neill, ...
 
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024Finding Java's Hidden Performance Traps @ DevoxxUK 2024
Finding Java's Hidden Performance Traps @ DevoxxUK 2024
 
Exploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with MilvusExploring Multimodal Embeddings with Milvus
Exploring Multimodal Embeddings with Milvus
 
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​Elevate Developer Efficiency & build GenAI Application with Amazon Q​
Elevate Developer Efficiency & build GenAI Application with Amazon Q​
 

Http4s

  • 1. Presented By: Swantika Gupta Hands-On 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. Agenda Introduction to http4s http4s DSL http4s Streaming Nature http4s Support for Circe Request - Response Model Creating Endpoint Creating Server Matching Requests Sending RAW JSON Extracting Requests Receiving RAW JSON EntityBody[ F]
  • 4. http4s - What makes it different? Define Values Light-weight Product Quality Typeful Pure Functional Performant Streaming Cross - Platform
  • 5. http4s - Request and Response type HttpRoutes = Kleisli[OptionT[F, *], Request, Response], Request -> Response Request -> Option[Response] Request -> F[Option[Response]] Kleisli[OptionT[F, *], Request, Response]
  • 6. http4s DSL Defining a simple endpoint implicit val runtime: IORuntime = cats.effect.unsafe.IORuntime.global val route: HttpRoutes[IO] = HttpRoutes.of[IO] { case GET -> Root / "length" / str => Ok(str.length.toString) } Request Type Endpoint Behavior GET (/POST/PUT) /length/{str} str.length.toString
  • 7. http4s DSL Running a Server BlazeServerBuilder[IO] .bindHttp(8080, "localhost") .withHttpApp(app) .resource .useForever .as(ExitCode.Success) val app = Router( “/” -> route, “/api” -> servicesAPI ) .orNotFound
  • 8. http4s DSL Matching & Extracting Requests HttpRoutes.of[IO] { case GET -> Root / "hello" / name => Ok(s"Hello, ${name}!") } HttpRoutes.of[IO] { case GET -> "hello" /: rest => Ok(s"""Hello, ${rest.segments.mkString(" and ")}!""") } HttpRoutes.of[IO] { case GET -> Root / file ~ "json" => Ok(s"""{"response": "You asked for $file"}""") } ● The -> Object and Matching Paths
  • 9. http4s DSL Matching & Extracting Requests def getUserName(userId: Int): IO[String] = ??? val usersService = HttpRoutes.of[IO] { case GET -> Root / "users" / IntVar(userId) => Ok(getUserName(userId)) } object LocalDateVar { def unapply(str: String): Option[LocalDate] = { if (!str.isEmpty) Try(LocalDate.parse(str)).toOption else None } } def getTemperatureForecast(date: LocalDate): IO[Double] = IO(42.23) val dailyWeatherService = HttpRoutes.of[IO] { case GET -> Root / "weather" / "temperature" / LocalDateVar(localDate) => Ok(getTemperatureForecast(localDate) .map(s"The temperature on $localDate will be: " + _)) } // /weather/temperature/2016-11-05 ● Handling Path Parameters
  • 10. object FullNameAndIDExtractor extends MatrixVar("name", List("first", "last", "id")) val greetingWithIdService = HttpRoutes.of[IO] { case GET -> Root / "hello" / FullNameAndIDExtractor(first, last, IntVar(id)) / "greeting" => Ok(s"Hello, $first $last. Your User ID is $id.") } // /hello/name;first=john;last=doe;id=123/greeting ● Handling Matrix Path Parameters http4s DSL Matching & Extracting Requests
  • 11. object CountryQueryParamMatcher extends QueryParamDecoderMatcher[String]("country") implicit val yearQueryParamDecoder: QueryParamDecoder[Year] = QueryParamDecoder[Int].map(Year.of) object YearQueryParamMatcher extends QueryParamDecoderMatcher[Year]("year") val averageTemperatureService = HttpRoutes.of[IO] { case GET -> Root / "weather" / "temperature" :? CountryQueryParamMatcher(country) +& YearQueryParamMatcher(year) => Ok(getAverageTemperatureForCountryAndYear(country, year) .map(s"Average temperature for $country in $year was: " + _)) } ● Handling Query Parameters - QueryParamDecoderMatcher http4s DSL Matching & Extracting Requests
  • 12. implicit val yearQueryParamDecoder: QueryParamDecoder[Year] = QueryParamDecoder[Int].map(Year.of) 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)) } } ● Handling Query Parameters - OptionalQueryParamDecoderMatcher http4s DSL Matching & Extracting Requests
  • 13. implicit val yearQueryParamDecoder: QueryParamDecoder[Year] = QueryParamDecoder[Int] .emap(i => Try(Year.of(i)) .toEither .leftMap(t => ParseFailure(t.getMessage, t.getMessage) ) ) object YearQueryParamMatcher extends ValidatingQueryParamDecoderMatcher[Year]("year") val routes = HttpRoutes.of[IO] { case GET -> Root / "temperature" :? YearQueryParamMatcher(yearValidated) => yearValidated.fold( parseFailures => BadRequest("unable to parse argument year"), year => Ok(getAverageTemperatureForYear(year)) ) } ● Handling Query Parameters - ValidatingQueryParamDecoderMatcher http4s DSL Matching & Extracting Requests
  • 14. object LongParamMatcher extends OptionalValidatingQueryParamDecoderMatcher[Long]("long") val routes = HttpRoutes.of[IO] { 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") } } ● Handling Query Parameters - OptionalValidatingQueryParamDecoderMatcher http4s DSL Matching & Extracting Requests
  • 15. http4s Streaming Nature Request[F] / R esponse[F] EntityBody[F] Stream[F, Byte] EntityEncoder / EntityDecoder Raw Data Types: String, File, InputStream JSON Support: curve, json4s-native XML Support: scala-xml
  • 16. http4s JSON Codec - Circe import io.circe.syntax._ case class Hello(name: String) implicit val HelloEncoder: Encoder[Hello] = Encoder.instance { (hello: Hello) => json"""{"hello": ${hello.name}}""" } Hello("Alice").asJson // res3: Json = JObject(value = object[hello -> "Alice"]) import io.circe.generic.auto._ case class User(name: String) User("Alice").asJson // res4: Json = JObject(value = object[name -> "Alice"]) Ok(Hello("Alice").asJson).unsafeRunSync() POST(User("Bob").asJson, uri"/hello") ● Sending Raw JSON
  • 17. http4s JSON Codec - Circe Ok("""{"name":"Alice"}""").flatMap(_.as[Json]).unsafeRunS ync() // res8: Json = JObject(value = object[name -> "Alice"]) POST("""{"name":"Bob"}""", uri"/hello").as[Json].unsafeRunSync() // res9: Json = JObject(value = object[name -> "Bob"]) case class User(name: String) implicit val userDecoder = jsonOf[IO, User] Ok("""{"name":"Alice"}""").flatMap(_.as[User]).unsafeRunS ync() // res10: User = User(name = "Alice") POST("""{"name":"Bob"}""", uri"/hello").as[User].unsafeRunSync() // res11: User = User(name = "Bob") ● Receiving Raw JSON
  • 18. http4s JSON Codec - Circe // Server import io.circe.generic.auto._ case class User(name: String) case class Hello(greeting: String) implicit val decoder = jsonOf[IO, User] val jsonApp = HttpRoutes.of[IO] { case req @ POST -> Root / "hello" => for { user <- req.as[User] // Decode resp <- Ok(Hello(user.name).asJson) // Encode } yield (resp) }.orNotFound ● Combining Encoder and Decoder // Client import io.circe.generic.auto._ def helloClient(name: String): IO[Hello] = { val req = POST(User(name).asJson, uri"http://localhost:8080/hello") EmberClientBuilder.default[IO].build.use { httpClient => httpClient.expect(req)(jsonOf[IO, Hello]) } } helloClient("Alice").unsafeRunSync()
  • 19. Demo
  • 20. Thank You ! Get in touch with us: Scala Studio, Knoldus