SlideShare a Scribd company logo
1 of 23
Download to read offline
Functional, Type-safe,
Testable Microservices
with ZIO and gRPC
Nadav Samet
https://www.linkedin.com/in/nadav-samet/
July 16, 2020
Agenda
Microservices
gRPC and why not JSON
gRPC in Java and Scala
Why use ZIO for gRPC
ZIO and gRPC In Action
Live demo!
1
2
3
Microservice Architecture
$
</>
Why Microservices?
Deployed Independently
Faster deployments and
increased team autonomy.
Technology Heterogeneity
Use the right technology
for each job.
Scaling and Resilience
Failures can be isolated.
Scale only what needs to
be scaled.
Microservices: Types of Protocols
Ad-hoc
● JSON over HTTP
● Binary over TCP
Typically with no
machine-readable schema.
Message-based
● gRPC
● Thrift
● Twirp
Formal API contract.
Machine-readable schema.
Clients automatically
generated.
Data-oriented
● GraphQL
Designed for querying and
mutating data.
Clients automatically
generated.
Used as outer layer, not
between internal layers.
JSON over HTTP (REST): Pros and Cons
● No machine-readable API contract
● Custom libraries
● No advanced features
○ streaming, cancellations, retries,
timeouts
● Slow performance
● Ubiquitous
● Easy to understand
● Great tooling
What is gRPC?
● High-performance RPC framework
● Based on Protocol Buffers
● Type-safe API schema
● Supports many languages
● Runs on many platforms
● Allows schema evolution
● Advanced features:
○ Streaming
○ Cancellations
○ Deadlines
gRPC libraries for Scala and Java
● grpc-java
● ScalaPB gRPC
● Akka gRPC
● fs2-grpc
● zio-grpc
Why a new gRPC solution for ZIO?
ZIO gRPC builds on the unique strengths of ZIO:
✓ High performance
✓ RPC calls are functional effects (pure values: composable and combinable)
✓ Easy request cancellations via fiber interrupts
✓ Resource release guaranteed
✓ Precise failure tracking with no exceptions
✓ Combinable effectful streams with ZStream
✓ Dependency injection with ZLayer
Teaser on RPC cancellations
if (Context.current().isCancelled()) {
responseObserver.onError(
Status.CANCELLED.withDescription("Cancelled")
.asRuntimeException());
return;
}
In grpc-java:
Connection db = Database.connect();
try {
// do things with DB
} finally {
db.disconnect();
}
ZIO.bracket(Database.connect)(_.disconnect()) {
db =>
// do things with db
}
In ZIO gRPC:
Teaser on RPC cancellations
if (Context.current().isCancelled()) {
responseObserver.onError(
Status.CANCELLED.withDescription("Cancelled")
.asRuntimeException());
return;
}
In grpc-java:
Connection db = Database.connect();
try {
// do things with DB
} finally {
db.disconnect();
}
ZIO.bracket(Database.connect)(_.disconnect()) {
db =>
(effect1 *> effect2).uninterruptible *>
effect3
}
In ZIO gRPC:
AnyHike
A purely functional type-safe
hike logging service with ZIO
and gRPC.
Location message
syntax = "proto3";
message Location {
double lat = 1;
double lng = 2;
int64 timestamp = 3;
}
final case class Location(
lat: Double, lng: Double, timestamp: Long) {
def toByteArray: Array[Byte] = { … }
}
object Location {
def parseFrom(bs: Array[Byte]): Location = { … }
}
val l = Location(lat=37.3895, lng= -118.7588, timestamp=System.currentTimeMillis())
l.toByteArray.toVector
// Vector(9, 96, -27, -48, 34, -37, -79, 66, 64, 17, 27, 13, -32, 45, -112, ...)
Location.parseFrom(Array[Byte](9, 96, -27, ...))
// Location(37.3895,-118.7588,1594239025145)
AnyHike: Service Definition
service HikeStore {
rpc AddLocations (AddLocationsRequest ) returns (AddLocationsResponse );
rpc GetLocations (GetLocationsRequest ) returns (GetLocationsResponse );
rpc StreamLocations (GetLocationsRequest ) returns (stream Location );
}
message Location {
double lat = 1;
double lng = 2;
int64 timestamp = 3;
}
message AddLocationsRequest {
repeated Location locations = 1;
}
message AddLocationsResponse {
int32 size = 1; // current number of locations
}
message GetLocationsRequest { }
message GetLocationsResponse {
repeated Location locations = 1;
}
AnyHike: Service Definition
service HikeStore {
rpc AddLocations (AddLocationsRequest ) returns (AddLocationsResponse );
rpc GetLocations (GetLocationsRequest ) returns (GetLocationsResponse );
rpc StreamLocations (GetLocationsRequest ) returns (stream Location );
}
message Location {
double lat = 1;
double lng = 2;
int64 timestamp = 3;
}
message AddLocationsRequest {
repeated Location locations = 1;
}
message AddLocationsResponse {
int32 size = 1; // current number of locations
}
message GetLocationsRequest { }
message GetLocationsResponse {
repeated Location locations = 1;
}
AnyHike: Service Definition
trait HikeStore {
def addLocations(req: AddLocationsRequest): IO[Status, AddLocationsResponse]
def getLocations(req: GetLocationsRequest): IO[Status, GetLocationsResponse]
def streamLocations(req: GetLocationsRequest): zio.Stream[Status, Location]
}
service HikeStore {
rpc AddLocations (AddLocationsRequest ) returns (AddLocationsResponse );
rpc GetLocations (GetLocationsRequest ) returns (GetLocationsResponse );
rpc StreamLocations (GetLocationsRequest ) returns (stream Location);
}
IO[E, A]: effect that may succeed with a value of type A or fail with a value of type E.
Stream[E, A]: effectful stream that produces values of type A and can potentially fail with
a value of type E.
HikeStore: Client interpretation
trait HikeStore {
def addLocations(req: AddLocationsRequest): IO[Status, AddLocationsResponse]
def getLocations(req: GetLocationsRequest): IO[Status, GetLocationsResponse]
def streamLocations(req: GetLocationsRequest): zio.Stream[Status, Location]
}
val client: HikeStore = connect() // connect to service
client.addLocations(AddLocationsRequest(Seq(Location(12.34, 56.78))))
HikeStore: Server interpretation
object HikeStoreServer extends HikeStore {
def addLocations(request: AddLocationsRequest) = IO.succeed(AddLocationsResponse(17))
// more methods
}
AnyHike: Environment and Context
trait ZHikeStore[R, Context] {
def addLocations(req: AddLocationsRequest): ZIO[R with Context, Status, AddLocationsResponse]
def getLocations(req: GetLocationsRequest): ZIO[R with Context, Status, GetLocationsResponse]
def streamLocations(req: GetLocationsRequest): ZStream[R with Context, Status, Location]
}
type HikeStore = ZHikeStore[Any, Any]
Dependencies Headers (Metadata)
AnyHike: Service Definition
case class User(name: String)
object HikeStoreImpl extends ZHikeStore[Any, Has[User]] {
def addLocations(request: AddLocationsRequest): ZIO[Has[User],Status,AddLocationsResponse] =
for {
user <- ZIO.service[User]
p <- doSomething(user.name)
} yield AddLocationsResponse(p.result)
// ...
def authenticate(rc: RequestContext): IO[Status, User] =
rc.metadata.get(UserKey).flatMap {
case Some("bob") => IO.fail(Status.PERMISSION_DENIED.withDescription("You are not allowed!"))
case Some(name) => IO.succeed(User(name))
case None => IO.fail(Status.UNAUTHENTICATED)
}
val hikeStore: ZHikeStore[Any, Has[RequestContext]] = HikeStoreImpl.transformContextM(authenticate)
Dependencies Context
Service transformations
ZHikeStore[Any, Has[User]] which expands to {
def addLocations(req: AddLocationsRequest):
ZIO[Has[User], Status, AddLocationsResponse]
def getLocations(req: GetLocationsRequest):
ZIO[Has[User], Status, GetLocationsResponse]
def streamLocations(req: GetLocationsRequest):
ZStream[Has[User], Status, Location]
}
Dependencies Context
ZHikeStore[Any, Has[RequestContext]] which expands to {
def addLocations(req: AddLocationsRequest):
ZIO[Has[RequestContext], Status, AddLocationsResponse]
def getLocations(req: GetLocationsRequest):
ZIO[Has[RequestContext], Status, GetLocationsResponse]
def streamLocations(req: GetLocationsRequest):
ZStream[Has[RequestContext], Status, Location]
}
Applies the same effectful transformation to all RPC methods:
● Authentication and Authorization
● Logging and tracing
● Global policies (timeouts for all methods)
Demo!
Conclusion
It’s easy to get started. Create a client and a service in minutes
and build your next API on a modern effect system!
Links:
● ZIO gRPC: https://github.com/scalapb/zio-grpc/
● ScalaPB: https://scalapb.github.io/
● Gitter: https://gitter.im/ScalaPB/community

More Related Content

What's hot

Optimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with TruffleOptimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with TruffleStefan Marr
 
Go and Uber’s time series database m3
Go and Uber’s time series database m3Go and Uber’s time series database m3
Go and Uber’s time series database m3Rob Skillington
 
Async await in C++
Async await in C++Async await in C++
Async await in C++cppfrug
 
[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent Programming[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent ProgrammingTobias Lindaaker
 
Qtp realtime scripts
Qtp realtime scriptsQtp realtime scripts
Qtp realtime scriptsRamu Palanki
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyIván López Martín
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streamsmattpodwysocki
 
Exploiting Concurrency with Dynamic Languages
Exploiting Concurrency with Dynamic LanguagesExploiting Concurrency with Dynamic Languages
Exploiting Concurrency with Dynamic LanguagesTobias Lindaaker
 
Performance in .net best practices
Performance in .net best practicesPerformance in .net best practices
Performance in .net best practicesCodecamp Romania
 
Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
Beginning direct3d gameprogrammingcpp02_20160324_jintaeksBeginning direct3d gameprogrammingcpp02_20160324_jintaeks
Beginning direct3d gameprogrammingcpp02_20160324_jintaeksJinTaek Seo
 
20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting StartedTeerawat Issariyakul
 
Blocks & GCD
Blocks & GCDBlocks & GCD
Blocks & GCDrsebbe
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015NAVER / MusicPlatform
 
Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014Mark Rees
 
06 - Qt Communication
06 - Qt Communication06 - Qt Communication
06 - Qt CommunicationAndreas Jakl
 
C++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogrammingC++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogrammingcppfrug
 
Qtp+real time+test+script
Qtp+real time+test+scriptQtp+real time+test+script
Qtp+real time+test+scriptRamu Palanki
 

What's hot (20)

Optimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with TruffleOptimizing Communicating Event-Loop Languages with Truffle
Optimizing Communicating Event-Loop Languages with Truffle
 
Return of c++
Return of c++Return of c++
Return of c++
 
Go and Uber’s time series database m3
Go and Uber’s time series database m3Go and Uber’s time series database m3
Go and Uber’s time series database m3
 
Async await in C++
Async await in C++Async await in C++
Async await in C++
 
[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent Programming[JavaOne 2011] Models for Concurrent Programming
[JavaOne 2011] Models for Concurrent Programming
 
Qtp realtime scripts
Qtp realtime scriptsQtp realtime scripts
Qtp realtime scripts
 
ConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with GroovyConFess Vienna 2015 - Metaprogramming with Groovy
ConFess Vienna 2015 - Metaprogramming with Groovy
 
Cascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the StreamsCascadia.js: Don't Cross the Streams
Cascadia.js: Don't Cross the Streams
 
Exploiting Concurrency with Dynamic Languages
Exploiting Concurrency with Dynamic LanguagesExploiting Concurrency with Dynamic Languages
Exploiting Concurrency with Dynamic Languages
 
Performance in .net best practices
Performance in .net best practicesPerformance in .net best practices
Performance in .net best practices
 
Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
Beginning direct3d gameprogrammingcpp02_20160324_jintaeksBeginning direct3d gameprogrammingcpp02_20160324_jintaeks
Beginning direct3d gameprogrammingcpp02_20160324_jintaeks
 
20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started20100712-OTcl Command -- Getting Started
20100712-OTcl Command -- Getting Started
 
Blocks & GCD
Blocks & GCDBlocks & GCD
Blocks & GCD
 
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
서버 개발자가 바라 본 Functional Reactive Programming with RxJava - SpringCamp2015
 
Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014Seeing with Python presented at PyCon AU 2014
Seeing with Python presented at PyCon AU 2014
 
NS2 Classifiers
NS2 ClassifiersNS2 Classifiers
NS2 Classifiers
 
06 - Qt Communication
06 - Qt Communication06 - Qt Communication
06 - Qt Communication
 
C++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogrammingC++ How I learned to stop worrying and love metaprogramming
C++ How I learned to stop worrying and love metaprogramming
 
Qtp+real time+test+script
Qtp+real time+test+scriptQtp+real time+test+script
Qtp+real time+test+script
 
C++ Coroutines
C++ CoroutinesC++ Coroutines
C++ Coroutines
 

Similar to Functional, Type-safe, Testable Microservices with ZIO and gRPC

OrientDB - The 2nd generation of (multi-model) NoSQL
OrientDB - The 2nd generation of  (multi-model) NoSQLOrientDB - The 2nd generation of  (multi-model) NoSQL
OrientDB - The 2nd generation of (multi-model) NoSQLRoberto Franchini
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeKAI CHU CHUNG
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication developmentGanesh Gembali
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Rightmircodotta
 
Finding OOMS in Legacy Systems with the Syslog Telegraf Plugin
Finding OOMS in Legacy Systems with the Syslog Telegraf PluginFinding OOMS in Legacy Systems with the Syslog Telegraf Plugin
Finding OOMS in Legacy Systems with the Syslog Telegraf PluginInfluxData
 
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays
 
Core2 Document - Java SCORE Overview.pptx.pdf
Core2 Document - Java SCORE Overview.pptx.pdfCore2 Document - Java SCORE Overview.pptx.pdf
Core2 Document - Java SCORE Overview.pptx.pdfThchTrngGia
 
Microservices Communication Patterns with gRPC
Microservices Communication Patterns with gRPCMicroservices Communication Patterns with gRPC
Microservices Communication Patterns with gRPCWSO2
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomyDongmin Yu
 
OpenCensus with Prometheus and Kubernetes
OpenCensus with Prometheus and KubernetesOpenCensus with Prometheus and Kubernetes
OpenCensus with Prometheus and KubernetesJinwoong Kim
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaSpark Summit
 
CRUD Operation With Dgraph
CRUD Operation With DgraphCRUD Operation With Dgraph
CRUD Operation With DgraphKnoldus Inc.
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorialKat Roque
 
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}Md. Sadhan Sarker
 
Geo script opengeo spring 2013
Geo script opengeo spring 2013Geo script opengeo spring 2013
Geo script opengeo spring 2013Ilya Rosenfeld
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScriptQiangning Hong
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing UpDavid Padbury
 

Similar to Functional, Type-safe, Testable Microservices with ZIO and gRPC (20)

OrientDB - The 2nd generation of (multi-model) NoSQL
OrientDB - The 2nd generation of  (multi-model) NoSQLOrientDB - The 2nd generation of  (multi-model) NoSQL
OrientDB - The 2nd generation of (multi-model) NoSQL
 
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with easeGDG Devfest 2019 - Build go kit microservices at kubernetes with ease
GDG Devfest 2019 - Build go kit microservices at kubernetes with ease
 
Mobile webapplication development
Mobile webapplication developmentMobile webapplication development
Mobile webapplication development
 
Lightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just RightLightbend Lagom: Microservices Just Right
Lightbend Lagom: Microservices Just Right
 
Data Pipeline at Tapad
Data Pipeline at TapadData Pipeline at Tapad
Data Pipeline at Tapad
 
Finding OOMS in Legacy Systems with the Syslog Telegraf Plugin
Finding OOMS in Legacy Systems with the Syslog Telegraf PluginFinding OOMS in Legacy Systems with the Syslog Telegraf Plugin
Finding OOMS in Legacy Systems with the Syslog Telegraf Plugin
 
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
apidays LIVE Helsinki - Implementing OpenAPI and GraphQL Services with gRPC b...
 
Core2 Document - Java SCORE Overview.pptx.pdf
Core2 Document - Java SCORE Overview.pptx.pdfCore2 Document - Java SCORE Overview.pptx.pdf
Core2 Document - Java SCORE Overview.pptx.pdf
 
Microservices Communication Patterns with gRPC
Microservices Communication Patterns with gRPCMicroservices Communication Patterns with gRPC
Microservices Communication Patterns with gRPC
 
Presto anatomy
Presto anatomyPresto anatomy
Presto anatomy
 
OpenCensus with Prometheus and Kubernetes
OpenCensus with Prometheus and KubernetesOpenCensus with Prometheus and Kubernetes
OpenCensus with Prometheus and Kubernetes
 
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-MallaKerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
Kerberizing Spark: Spark Summit East talk by Abel Rincon and Jorge Lopez-Malla
 
CRUD Operation With Dgraph
CRUD Operation With DgraphCRUD Operation With Dgraph
CRUD Operation With Dgraph
 
NodeJS
NodeJSNodeJS
NodeJS
 
Ajax tutorial
Ajax tutorialAjax tutorial
Ajax tutorial
 
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
Up and Running with gRPC & Cloud Career [GDG-Cloud-Dhaka-IO/2022}
 
Switch to Backend 2023
Switch to Backend 2023Switch to Backend 2023
Switch to Backend 2023
 
Geo script opengeo spring 2013
Geo script opengeo spring 2013Geo script opengeo spring 2013
Geo script opengeo spring 2013
 
服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript服务框架: Thrift & PasteScript
服务框架: Thrift & PasteScript
 
JavaScript Growing Up
JavaScript Growing UpJavaScript Growing Up
JavaScript Growing Up
 

Recently uploaded

XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsMehedi Hasan Shohan
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationkaushalgiri8080
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...MyIntelliSource, Inc.
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutionsmonugehlot87
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - InfographicHr365.us smith
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)OPEN KNOWLEDGE GmbH
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfkalichargn70th171
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样umasea
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWave PLM
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyFrank van der Linden
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?Watsoo Telematics
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number SystemsJheuzeDellosa
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataBradBedford3
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfPower Karaoke
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...MyIntelliSource, Inc.
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...aditisharan08
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 

Recently uploaded (20)

XpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software SolutionsXpertSolvers: Your Partner in Building Innovative Software Solutions
XpertSolvers: Your Partner in Building Innovative Software Solutions
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
Project Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanationProject Based Learning (A.I).pptx detail explanation
Project Based Learning (A.I).pptx detail explanation
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
buds n tech IT solutions
buds n  tech IT                solutionsbuds n  tech IT                solutions
buds n tech IT solutions
 
Asset Management Software - Infographic
Asset Management Software - InfographicAsset Management Software - Infographic
Asset Management Software - Infographic
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)Der Spagat zwischen BIAS und FAIRNESS (2024)
Der Spagat zwischen BIAS und FAIRNESS (2024)
 
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdfThe Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
The Essentials of Digital Experience Monitoring_ A Comprehensive Guide.pdf
 
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
办理学位证(UQ文凭证书)昆士兰大学毕业证成绩单原版一模一样
 
What is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need ItWhat is Fashion PLM and Why Do You Need It
What is Fashion PLM and Why Do You Need It
 
Engage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The UglyEngage Usergroup 2024 - The Good The Bad_The Ugly
Engage Usergroup 2024 - The Good The Bad_The Ugly
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?What are the features of Vehicle Tracking System?
What are the features of Vehicle Tracking System?
 
What is Binary Language? Computer Number Systems
What is Binary Language?  Computer Number SystemsWhat is Binary Language?  Computer Number Systems
What is Binary Language? Computer Number Systems
 
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer DataAdobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
Adobe Marketo Engage Deep Dives: Using Webhooks to Transfer Data
 
The Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdfThe Evolution of Karaoke From Analog to App.pdf
The Evolution of Karaoke From Analog to App.pdf
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...Unit 1.1 Excite Part 1, class 9, cbse...
Unit 1.1 Excite Part 1, class 9, cbse...
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 

Functional, Type-safe, Testable Microservices with ZIO and gRPC

  • 1. Functional, Type-safe, Testable Microservices with ZIO and gRPC Nadav Samet https://www.linkedin.com/in/nadav-samet/ July 16, 2020
  • 2. Agenda Microservices gRPC and why not JSON gRPC in Java and Scala Why use ZIO for gRPC ZIO and gRPC In Action Live demo! 1 2 3
  • 4. Why Microservices? Deployed Independently Faster deployments and increased team autonomy. Technology Heterogeneity Use the right technology for each job. Scaling and Resilience Failures can be isolated. Scale only what needs to be scaled.
  • 5. Microservices: Types of Protocols Ad-hoc ● JSON over HTTP ● Binary over TCP Typically with no machine-readable schema. Message-based ● gRPC ● Thrift ● Twirp Formal API contract. Machine-readable schema. Clients automatically generated. Data-oriented ● GraphQL Designed for querying and mutating data. Clients automatically generated. Used as outer layer, not between internal layers.
  • 6. JSON over HTTP (REST): Pros and Cons ● No machine-readable API contract ● Custom libraries ● No advanced features ○ streaming, cancellations, retries, timeouts ● Slow performance ● Ubiquitous ● Easy to understand ● Great tooling
  • 7. What is gRPC? ● High-performance RPC framework ● Based on Protocol Buffers ● Type-safe API schema ● Supports many languages ● Runs on many platforms ● Allows schema evolution ● Advanced features: ○ Streaming ○ Cancellations ○ Deadlines
  • 8. gRPC libraries for Scala and Java ● grpc-java ● ScalaPB gRPC ● Akka gRPC ● fs2-grpc ● zio-grpc
  • 9. Why a new gRPC solution for ZIO? ZIO gRPC builds on the unique strengths of ZIO: ✓ High performance ✓ RPC calls are functional effects (pure values: composable and combinable) ✓ Easy request cancellations via fiber interrupts ✓ Resource release guaranteed ✓ Precise failure tracking with no exceptions ✓ Combinable effectful streams with ZStream ✓ Dependency injection with ZLayer
  • 10. Teaser on RPC cancellations if (Context.current().isCancelled()) { responseObserver.onError( Status.CANCELLED.withDescription("Cancelled") .asRuntimeException()); return; } In grpc-java: Connection db = Database.connect(); try { // do things with DB } finally { db.disconnect(); } ZIO.bracket(Database.connect)(_.disconnect()) { db => // do things with db } In ZIO gRPC:
  • 11. Teaser on RPC cancellations if (Context.current().isCancelled()) { responseObserver.onError( Status.CANCELLED.withDescription("Cancelled") .asRuntimeException()); return; } In grpc-java: Connection db = Database.connect(); try { // do things with DB } finally { db.disconnect(); } ZIO.bracket(Database.connect)(_.disconnect()) { db => (effect1 *> effect2).uninterruptible *> effect3 } In ZIO gRPC:
  • 12. AnyHike A purely functional type-safe hike logging service with ZIO and gRPC.
  • 13. Location message syntax = "proto3"; message Location { double lat = 1; double lng = 2; int64 timestamp = 3; } final case class Location( lat: Double, lng: Double, timestamp: Long) { def toByteArray: Array[Byte] = { … } } object Location { def parseFrom(bs: Array[Byte]): Location = { … } } val l = Location(lat=37.3895, lng= -118.7588, timestamp=System.currentTimeMillis()) l.toByteArray.toVector // Vector(9, 96, -27, -48, 34, -37, -79, 66, 64, 17, 27, 13, -32, 45, -112, ...) Location.parseFrom(Array[Byte](9, 96, -27, ...)) // Location(37.3895,-118.7588,1594239025145)
  • 14. AnyHike: Service Definition service HikeStore { rpc AddLocations (AddLocationsRequest ) returns (AddLocationsResponse ); rpc GetLocations (GetLocationsRequest ) returns (GetLocationsResponse ); rpc StreamLocations (GetLocationsRequest ) returns (stream Location ); } message Location { double lat = 1; double lng = 2; int64 timestamp = 3; } message AddLocationsRequest { repeated Location locations = 1; } message AddLocationsResponse { int32 size = 1; // current number of locations } message GetLocationsRequest { } message GetLocationsResponse { repeated Location locations = 1; }
  • 15. AnyHike: Service Definition service HikeStore { rpc AddLocations (AddLocationsRequest ) returns (AddLocationsResponse ); rpc GetLocations (GetLocationsRequest ) returns (GetLocationsResponse ); rpc StreamLocations (GetLocationsRequest ) returns (stream Location ); } message Location { double lat = 1; double lng = 2; int64 timestamp = 3; } message AddLocationsRequest { repeated Location locations = 1; } message AddLocationsResponse { int32 size = 1; // current number of locations } message GetLocationsRequest { } message GetLocationsResponse { repeated Location locations = 1; }
  • 16. AnyHike: Service Definition trait HikeStore { def addLocations(req: AddLocationsRequest): IO[Status, AddLocationsResponse] def getLocations(req: GetLocationsRequest): IO[Status, GetLocationsResponse] def streamLocations(req: GetLocationsRequest): zio.Stream[Status, Location] } service HikeStore { rpc AddLocations (AddLocationsRequest ) returns (AddLocationsResponse ); rpc GetLocations (GetLocationsRequest ) returns (GetLocationsResponse ); rpc StreamLocations (GetLocationsRequest ) returns (stream Location); } IO[E, A]: effect that may succeed with a value of type A or fail with a value of type E. Stream[E, A]: effectful stream that produces values of type A and can potentially fail with a value of type E.
  • 17. HikeStore: Client interpretation trait HikeStore { def addLocations(req: AddLocationsRequest): IO[Status, AddLocationsResponse] def getLocations(req: GetLocationsRequest): IO[Status, GetLocationsResponse] def streamLocations(req: GetLocationsRequest): zio.Stream[Status, Location] } val client: HikeStore = connect() // connect to service client.addLocations(AddLocationsRequest(Seq(Location(12.34, 56.78))))
  • 18. HikeStore: Server interpretation object HikeStoreServer extends HikeStore { def addLocations(request: AddLocationsRequest) = IO.succeed(AddLocationsResponse(17)) // more methods }
  • 19. AnyHike: Environment and Context trait ZHikeStore[R, Context] { def addLocations(req: AddLocationsRequest): ZIO[R with Context, Status, AddLocationsResponse] def getLocations(req: GetLocationsRequest): ZIO[R with Context, Status, GetLocationsResponse] def streamLocations(req: GetLocationsRequest): ZStream[R with Context, Status, Location] } type HikeStore = ZHikeStore[Any, Any] Dependencies Headers (Metadata)
  • 20. AnyHike: Service Definition case class User(name: String) object HikeStoreImpl extends ZHikeStore[Any, Has[User]] { def addLocations(request: AddLocationsRequest): ZIO[Has[User],Status,AddLocationsResponse] = for { user <- ZIO.service[User] p <- doSomething(user.name) } yield AddLocationsResponse(p.result) // ... def authenticate(rc: RequestContext): IO[Status, User] = rc.metadata.get(UserKey).flatMap { case Some("bob") => IO.fail(Status.PERMISSION_DENIED.withDescription("You are not allowed!")) case Some(name) => IO.succeed(User(name)) case None => IO.fail(Status.UNAUTHENTICATED) } val hikeStore: ZHikeStore[Any, Has[RequestContext]] = HikeStoreImpl.transformContextM(authenticate) Dependencies Context
  • 21. Service transformations ZHikeStore[Any, Has[User]] which expands to { def addLocations(req: AddLocationsRequest): ZIO[Has[User], Status, AddLocationsResponse] def getLocations(req: GetLocationsRequest): ZIO[Has[User], Status, GetLocationsResponse] def streamLocations(req: GetLocationsRequest): ZStream[Has[User], Status, Location] } Dependencies Context ZHikeStore[Any, Has[RequestContext]] which expands to { def addLocations(req: AddLocationsRequest): ZIO[Has[RequestContext], Status, AddLocationsResponse] def getLocations(req: GetLocationsRequest): ZIO[Has[RequestContext], Status, GetLocationsResponse] def streamLocations(req: GetLocationsRequest): ZStream[Has[RequestContext], Status, Location] } Applies the same effectful transformation to all RPC methods: ● Authentication and Authorization ● Logging and tracing ● Global policies (timeouts for all methods)
  • 22. Demo!
  • 23. Conclusion It’s easy to get started. Create a client and a service in minutes and build your next API on a modern effect system! Links: ● ZIO gRPC: https://github.com/scalapb/zio-grpc/ ● ScalaPB: https://scalapb.github.io/ ● Gitter: https://gitter.im/ScalaPB/community