SlideShare ist ein Scribd-Unternehmen logo
1 von 23
Downloaden Sie, um offline zu lesen
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

Weitere ähnliche Inhalte

Was ist angesagt?

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
 

Was ist angesagt? (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
 

Ähnlich wie 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
 

Ähnlich wie 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
 

Kürzlich hochgeladen

VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsJhone kinadey
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfonteinmasabamasaba
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Bert Jan Schrijver
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile EnvironmentVictorSzoltysek
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...Health
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...masabamasaba
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...masabamasaba
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyviewmasabamasaba
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsArshad QA
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastPapp Krisztián
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...Shane Coughlan
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdfPearlKirahMaeRagusta1
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisamasabamasaba
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...masabamasaba
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2
 

Kürzlich hochgeladen (20)

VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With SimplicityWSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
WSO2Con2024 - Enabling Transactional System's Exponential Growth With Simplicity
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
%in Stilfontein+277-882-255-28 abortion pills for sale in Stilfontein
 
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
Devoxx UK 2024 - Going serverless with Quarkus, GraalVM native images and AWS...
 
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT  - Elevating Productivity in Today's Agile EnvironmentHarnessing ChatGPT  - Elevating Productivity in Today's Agile Environment
Harnessing ChatGPT - Elevating Productivity in Today's Agile Environment
 
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
+971565801893>>SAFE AND ORIGINAL ABORTION PILLS FOR SALE IN DUBAI AND ABUDHAB...
 
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
WSO2CON 2024 - Cloud Native Middleware: Domain-Driven Design, Cell-Based Arch...
 
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
%+27788225528 love spells in Huntington Beach Psychic Readings, Attraction sp...
 
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
%+27788225528 love spells in Boston Psychic Readings, Attraction spells,Bring...
 
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
%in Hazyview+277-882-255-28 abortion pills for sale in Hazyview
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
Architecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the pastArchitecture decision records - How not to get lost in the past
Architecture decision records - How not to get lost in the past
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
OpenChain - The Ramifications of ISO/IEC 5230 and ISO/IEC 18974 for Legal Pro...
 
Define the academic and professional writing..pdf
Define the academic and professional writing..pdfDefine the academic and professional writing..pdf
Define the academic and professional writing..pdf
 
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa%in tembisa+277-882-255-28 abortion pills for sale in tembisa
%in tembisa+277-882-255-28 abortion pills for sale in tembisa
 
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
%+27788225528 love spells in Atlanta Psychic Readings, Attraction spells,Brin...
 
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
WSO2Con2024 - From Code To Cloud: Fast Track Your Cloud Native Journey with C...
 

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