SlideShare una empresa de Scribd logo
1 de 47
Descargar para leer sin conexión
DESIGNING A
FUNCTIONAL GRAPHQL LIBRARY
Functional Scala 2019
WHO AM I?
> Pierre Ricadat aka @ghostdogpr
>
!
exiled in
"
> Contributor to ZIO
> Creator of Caliban
GRAPHQL ?
GRAPHQL IN A NUTSHELL
> query language for APIs
> server exposes a typed schema
> client asks for what they want
> queries
> mutations
> subscriptions
WHY?
WHY CREATE A GRAPHQL LIBRARY?
> Sangria is great but...
> lots of boilerplate
> Future-based
> schema and resolver tied together
> interesting approach by Morpheus (Haskell)
> it's fun!
GOALS
> minimal boilerplate
> purely functional
> strongly typed
> explicit errors
> ZIO
> schema / resolver separation
PLAN OF ACTION
query → parsing → validation → execution → result
↑
schema
QUERY PARSING
query → parsing → validation → execution → result
↑
schema
QUERY PARSING
GraphQL spec: https://graphql.github.io/graphql-spec/
QUERY PARSING
Fastparse: fast, easy to use, good documentation
def name[_: P]: P[String] = P(CharIn("_A-Za-z") ~~ CharIn("_0-9A-Za-z").repX).!
def fragmentName[_: P]: P[String] = P(name).filter(_ != "on")
def fragmentSpread[_: P]: P[FragmentSpread] =
P("..." ~ fragmentName ~ directives).map {
case (name, dirs) => FragmentSpread(name, dirs)
}
SCHEMA
query → parsing → validation → execution → result
↑
schema
SCHEMA
Idea from Morpheus:
derive GraphQL schema from basic types
SIMPLE API
type Queries {
pug: Pug!
}
case class Queries(pug: Pug)
OBJECTS
type Pug {
name: String!
nicknames: [String!]!
favoriteFood: String
}
case class Pug(
name: String,
nicknames: List[String],
favoriteFood: Option[String])
ENUMS
enum Color {
FAWN
BLACK
OTHER
}
sealed trait Color
case object FAWN extends Color
case object BLACK extends Color
case object OTHER extends Color
ARGUMENTS
type Queries {
pug(name: String!): Pug
}
case class PugName(name: String)
case class Queries(pug: PugName => Option[Pug])
EFFECTS
type Queries {
pug(name: String!): Pug
}
case class PugName(name: String)
case class Queries(pug: PugName => Task[Pug])
RESOLVER
simple value
case class PugName(name: String)
case class Queries(
pug: PugName => Task[Pug]
pugs: Task[List[Pug]]
)
val resolver = Queries(
args => PugService.findPug(args.name),
PugService.getAllPugs
)
SCHEMA
trait Schema[-R, T] {
// describe the type T
def toType(isInput: Boolean = false): __Type
// describe how to resolve a value of type T
def resolve(value: T): Step[R]
}
WHAT'S A STEP
> Pure Value (leaf)
> List
> Object
> Effect
> Stream
SCHEMA FOR STRING
implicit val stringSchema = new Schema[Any, String] {
def toType(isInput: Boolean = false): __Type =
__Type(__TypeKind.SCALAR, Some("String"))
def resolve(value: String): Step[R] =
PureStep(StringValue(value))
}
Schema for case classes and sealed traits?
MAGNOLIA
>
!
> ease of use
> compile time
> documentation, examples
>
"
> error messages (getting better!)
MAGNOLIA DERIVATION
def combine[T](
caseClass: CaseClass[Typeclass, T]): Typeclass[T]
def dispatch[T](
sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T]
VALIDATION
query → parsing → validation → execution → result
↑
schema
VALIDATION
Back to the specs
EXECUTION
query → parsing → validation → execution → result
↑
schema
EXECUTION
1. Schema + Resolver => Execution Plan (tree of Steps)
2. Filter Plan to include only requested fields
3. Reduce Plan to pure values and effects
4. Run effects
N+1 PROBLEM
{
orders { # fetches orders (1 query)
id
customer { # fetches customer (n queries)
name
}
}
}
QUERY OPTIMIZATION
Naive ZIO[R, E, A] version
val getAllUserIds: ZIO[Any, Nothing, List[Int]] = ???
def getUserNameById(id: Int): ZIO[Any, Nothing, String] = ???
for {
userIds <- getAllUserIds
userNames <- ZIO.foreachPar(userIds)(getUserNameById)
} yield userNames
QUERY OPTIMIZATION
Meet ZQuery[R, E, A]
val getAllUserIds: ZQuery[Any, Nothing, List[Int]] = ???
def getUserNameById(id: Int): ZQuery[Any, Nothing, String] = ???
for {
userIds <- getAllUserIds
userNames <- ZQuery.foreachPar(userIds)(getUserNameById)
} yield userNames
ZQUERY BENEFITS
> parallelize queries
> cache identical queries (deduplication)
> batch queries if batching function provided
ZQUERY
> courtesy of @adamgfraser
> based on paper on Haxl
> "There is no Fork: An Abstraction for Efficient,
Concurrent, and Concise Data Access"
> will be extracted to its own library at some point
INTROSPECTION
Dogfooding
case class __Introspection(
__schema: __Schema,
__type: __TypeArgs => __Type)
USAGE
1. Define your queries / mutations / subscriptions
2. Provide a Schema for custom types
3. Provide a resolver
4. Profit
1. DEFINE YOUR QUERIES
case class Pug(name: String, nicknames: List[String], favoriteFood: Option[String])
case class PugName(name: NonEmptyString)
case class Queries(pugs: Task[List[Pug]], pug: PugName => Task[Pug])
type Pug {
name: String!
nicknames: [String!]!
favoriteFood: String
}
type Queries {
pugs: [Pug!]
pug(name: String!): Pug
}
2. PROVIDE A SCHEMA FOR CUSTOM TYPES
implicit val nesSchema: Schema[NonEmptyString] =
Schema.stringSchema.contramap(_.value)
3. PROVIDE A RESOLVER
def getPugs: Task[List[Pug]] = ???
def getPug(name: String): Task[Pug] = ???
val queries = Queries(
getPugs,
args => getPug(args.name))
val resolver = RootResolver(queries)
4. PROFIT
val interpreter = graphQL(resolver)
for {
result <- interpreter.execute(query)
_ <- zio.console.putStrLn(result.toString)
} yield ()
HTTP4S MODULE
val route: HttpRoutes[RIO[R, *]] =
Http4sAdapter.makeRestService(interpreter)
val wsRoute: HttpRoutes[RIO[R, *]] =
Http4sAdapter.makeWebSocketService(interpreter)
SCALAJS
Few and modern dependencies
ScalaJS support for free
CATS COMPATIBILITY
caliban-cats module
def executeAsync[F[_]: Async](...)(
implicit runtime: Runtime[Any]): F[GraphQLResponse[E]]
def makeRestServiceF[F[_]: Effect, Q, M, S, E](...)(
implicit runtime: Runtime[Any]): HttpRoutes[F]
PERFORMANCE
Caliban is fast
Check benchmarks module on github
FUTURE
> Query analysis
> Middleware (query-level, field-level)
> Code generation
> Other HTTP adapters (Akka HTTP) <- help needed
> Client support
WANNA KNOW MORE?
> Website: https://ghostdogpr.github.io/caliban/
> ZIO Discord: #caliban
THANKS!QUESTIONS?

Más contenido relacionado

La actualidad más candente

Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with JasmineTim Tyrrell
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8XSolve
 
JavaScript Classes and Inheritance
JavaScript Classes and InheritanceJavaScript Classes and Inheritance
JavaScript Classes and Inheritancemarcheiligers
 
JDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJosé Paumard
 
PHP 8.1 - What's new and changed
PHP 8.1 - What's new and changedPHP 8.1 - What's new and changed
PHP 8.1 - What's new and changedAyesh Karunaratne
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScriptMichael Girouard
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaHermann Hueck
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6Fiyaz Hasan
 
Scala introduction
Scala introductionScala introduction
Scala introductionvito jeng
 
JavaScript Web Development
JavaScript Web DevelopmentJavaScript Web Development
JavaScript Web Developmentvito jeng
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)BoneyGawande
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghStuart Roebuck
 
Arrays &amp; functions in php
Arrays &amp; functions in phpArrays &amp; functions in php
Arrays &amp; functions in phpAshish Chamoli
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsFITC
 
ReactでGraphQLを使っている
ReactでGraphQLを使っているReactでGraphQLを使っている
ReactでGraphQLを使っているTakahiro Kobaru
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptecker
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)David de Boer
 
Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Alina Vilk
 
Building High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 AppsBuilding High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 AppsMichele Capra
 

La actualidad más candente (20)

Testing Javascript with Jasmine
Testing Javascript with JasmineTesting Javascript with Jasmine
Testing Javascript with Jasmine
 
Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8Xlab #1: Advantages of functional programming in Java 8
Xlab #1: Advantages of functional programming in Java 8
 
JavaScript Classes and Inheritance
JavaScript Classes and InheritanceJavaScript Classes and Inheritance
JavaScript Classes and Inheritance
 
JDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easyJDK8 : parallel programming made (too ?) easy
JDK8 : parallel programming made (too ?) easy
 
PHP 8.1 - What's new and changed
PHP 8.1 - What's new and changedPHP 8.1 - What's new and changed
PHP 8.1 - What's new and changed
 
Object Oriented JavaScript
Object Oriented JavaScriptObject Oriented JavaScript
Object Oriented JavaScript
 
Reactive Access to MongoDB from Scala
Reactive Access to MongoDB from ScalaReactive Access to MongoDB from Scala
Reactive Access to MongoDB from Scala
 
What’s new in C# 6
What’s new in C# 6What’s new in C# 6
What’s new in C# 6
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
JavaScript Web Development
JavaScript Web DevelopmentJavaScript Web Development
JavaScript Web Development
 
Java script advance-auroskills (2)
Java script advance-auroskills (2)Java script advance-auroskills (2)
Java script advance-auroskills (2)
 
Scala @ TechMeetup Edinburgh
Scala @ TechMeetup EdinburghScala @ TechMeetup Edinburgh
Scala @ TechMeetup Edinburgh
 
Java 8 Stream API (Valdas Zigas)
Java 8 Stream API (Valdas Zigas)Java 8 Stream API (Valdas Zigas)
Java 8 Stream API (Valdas Zigas)
 
Arrays &amp; functions in php
Arrays &amp; functions in phpArrays &amp; functions in php
Arrays &amp; functions in php
 
Test-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS ApplicationsTest-Driven Development of AngularJS Applications
Test-Driven Development of AngularJS Applications
 
ReactでGraphQLを使っている
ReactでGraphQLを使っているReactでGraphQLを使っている
ReactでGraphQLを使っている
 
Advanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScriptAdvanced Object-Oriented JavaScript
Advanced Object-Oriented JavaScript
 
Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)Being functional in PHP (DPC 2016)
Being functional in PHP (DPC 2016)
 
Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)Expression trees in c#, Алексей Голубь (Svitla Systems)
Expression trees in c#, Алексей Голубь (Svitla Systems)
 
Building High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 AppsBuilding High Performance and Reliable Windows Phone 8 Apps
Building High Performance and Reliable Windows Phone 8 Apps
 

Similar a Designing a Functional GraphQL Library

Thumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazThumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazAlexey Remnev
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondMario Fusco
 
NLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by OrdinaNLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by OrdinaMartijn Blankestijn
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Dhaval Dalal
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()daewon jeong
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8Kyle Smith
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CAlexis Gallagher
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1Jano Suchal
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Mario Camou Riveroll
 
How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Pythonkwatch
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday lifeAndrea Iacono
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java ProgrammersEric Pederson
 
Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioLuis Atencio
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: FunctionsAdam Crabtree
 
Querydsl fin jug - june 2012
Querydsl   fin jug - june 2012Querydsl   fin jug - june 2012
Querydsl fin jug - june 2012Timo Westkämper
 
Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Vadim Dubs
 

Similar a Designing a Functional GraphQL Library (20)

Java 8 Workshop
Java 8 WorkshopJava 8 Workshop
Java 8 Workshop
 
Thumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - JavazThumbtack Expertise Days # 5 - Javaz
Thumbtack Expertise Days # 5 - Javaz
 
FP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyondFP in Java - Project Lambda and beyond
FP in Java - Project Lambda and beyond
 
NLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by OrdinaNLJUG University Sessie: Java Reborn, Powered by Ordina
NLJUG University Sessie: Java Reborn, Powered by Ordina
 
Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)Currying and Partial Function Application (PFA)
Currying and Partial Function Application (PFA)
 
Scala is java8.next()
Scala is java8.next()Scala is java8.next()
Scala is java8.next()
 
What's new in Java 8
What's new in Java 8What's new in Java 8
What's new in Java 8
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-C
 
What is new in Java 8
What is new in Java 8What is new in Java 8
What is new in Java 8
 
Metaprogramovanie #1
Metaprogramovanie #1Metaprogramovanie #1
Metaprogramovanie #1
 
Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?Static or Dynamic Typing? Why not both?
Static or Dynamic Typing? Why not both?
 
How to make the fastest Router in Python
How to make the fastest Router in PythonHow to make the fastest Router in Python
How to make the fastest Router in Python
 
Functional Java 8 in everyday life
Functional Java 8 in everyday lifeFunctional Java 8 in everyday life
Functional Java 8 in everyday life
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Functional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis AtencioFunctional Programming in JavaScript by Luis Atencio
Functional Programming in JavaScript by Luis Atencio
 
LinkedIn TBC JavaScript 100: Functions
 LinkedIn TBC JavaScript 100: Functions LinkedIn TBC JavaScript 100: Functions
LinkedIn TBC JavaScript 100: Functions
 
Lambdas and Laughs
Lambdas and LaughsLambdas and Laughs
Lambdas and Laughs
 
Javascripting.pptx
Javascripting.pptxJavascripting.pptx
Javascripting.pptx
 
Querydsl fin jug - june 2012
Querydsl   fin jug - june 2012Querydsl   fin jug - june 2012
Querydsl fin jug - june 2012
 
Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.Javaz. Functional design in Java 8.
Javaz. Functional design in Java 8.
 

Último

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
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionSolGuruz
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Modelsaagamshah0812
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerThousandEyes
 
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.
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...ICS
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVshikhaohhpro
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...harshavardhanraghave
 
+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
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
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.
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Steffen Staab
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️anilsa9823
 

Último (20)

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
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Unlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language ModelsUnlocking the Future of AI Agents with Large Language Models
Unlocking the Future of AI Agents with Large Language Models
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
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...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Optimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTVOptimizing AI for immediate response in Smart CCTV
Optimizing AI for immediate response in Smart CCTV
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
Reassessing the Bedrock of Clinical Function Models: An Examination of Large ...
 
+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...
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
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 ...
 
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
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 

Designing a Functional GraphQL Library

  • 1. DESIGNING A FUNCTIONAL GRAPHQL LIBRARY Functional Scala 2019
  • 2. WHO AM I? > Pierre Ricadat aka @ghostdogpr > ! exiled in " > Contributor to ZIO > Creator of Caliban
  • 4. GRAPHQL IN A NUTSHELL > query language for APIs > server exposes a typed schema > client asks for what they want > queries > mutations > subscriptions
  • 6. WHY CREATE A GRAPHQL LIBRARY? > Sangria is great but... > lots of boilerplate > Future-based > schema and resolver tied together > interesting approach by Morpheus (Haskell) > it's fun!
  • 7. GOALS > minimal boilerplate > purely functional > strongly typed > explicit errors > ZIO > schema / resolver separation
  • 8. PLAN OF ACTION query → parsing → validation → execution → result ↑ schema
  • 9. QUERY PARSING query → parsing → validation → execution → result ↑ schema
  • 10. QUERY PARSING GraphQL spec: https://graphql.github.io/graphql-spec/
  • 11. QUERY PARSING Fastparse: fast, easy to use, good documentation def name[_: P]: P[String] = P(CharIn("_A-Za-z") ~~ CharIn("_0-9A-Za-z").repX).! def fragmentName[_: P]: P[String] = P(name).filter(_ != "on") def fragmentSpread[_: P]: P[FragmentSpread] = P("..." ~ fragmentName ~ directives).map { case (name, dirs) => FragmentSpread(name, dirs) }
  • 12. SCHEMA query → parsing → validation → execution → result ↑ schema
  • 13. SCHEMA Idea from Morpheus: derive GraphQL schema from basic types
  • 14. SIMPLE API type Queries { pug: Pug! } case class Queries(pug: Pug)
  • 15. OBJECTS type Pug { name: String! nicknames: [String!]! favoriteFood: String } case class Pug( name: String, nicknames: List[String], favoriteFood: Option[String])
  • 16. ENUMS enum Color { FAWN BLACK OTHER } sealed trait Color case object FAWN extends Color case object BLACK extends Color case object OTHER extends Color
  • 17. ARGUMENTS type Queries { pug(name: String!): Pug } case class PugName(name: String) case class Queries(pug: PugName => Option[Pug])
  • 18. EFFECTS type Queries { pug(name: String!): Pug } case class PugName(name: String) case class Queries(pug: PugName => Task[Pug])
  • 19. RESOLVER simple value case class PugName(name: String) case class Queries( pug: PugName => Task[Pug] pugs: Task[List[Pug]] ) val resolver = Queries( args => PugService.findPug(args.name), PugService.getAllPugs )
  • 20. SCHEMA trait Schema[-R, T] { // describe the type T def toType(isInput: Boolean = false): __Type // describe how to resolve a value of type T def resolve(value: T): Step[R] }
  • 21. WHAT'S A STEP > Pure Value (leaf) > List > Object > Effect > Stream
  • 22. SCHEMA FOR STRING implicit val stringSchema = new Schema[Any, String] { def toType(isInput: Boolean = false): __Type = __Type(__TypeKind.SCALAR, Some("String")) def resolve(value: String): Step[R] = PureStep(StringValue(value)) }
  • 23. Schema for case classes and sealed traits?
  • 24. MAGNOLIA > ! > ease of use > compile time > documentation, examples > " > error messages (getting better!)
  • 25. MAGNOLIA DERIVATION def combine[T]( caseClass: CaseClass[Typeclass, T]): Typeclass[T] def dispatch[T]( sealedTrait: SealedTrait[Typeclass, T]): Typeclass[T]
  • 26. VALIDATION query → parsing → validation → execution → result ↑ schema
  • 28. EXECUTION query → parsing → validation → execution → result ↑ schema
  • 29. EXECUTION 1. Schema + Resolver => Execution Plan (tree of Steps) 2. Filter Plan to include only requested fields 3. Reduce Plan to pure values and effects 4. Run effects
  • 30. N+1 PROBLEM { orders { # fetches orders (1 query) id customer { # fetches customer (n queries) name } } }
  • 31. QUERY OPTIMIZATION Naive ZIO[R, E, A] version val getAllUserIds: ZIO[Any, Nothing, List[Int]] = ??? def getUserNameById(id: Int): ZIO[Any, Nothing, String] = ??? for { userIds <- getAllUserIds userNames <- ZIO.foreachPar(userIds)(getUserNameById) } yield userNames
  • 32. QUERY OPTIMIZATION Meet ZQuery[R, E, A] val getAllUserIds: ZQuery[Any, Nothing, List[Int]] = ??? def getUserNameById(id: Int): ZQuery[Any, Nothing, String] = ??? for { userIds <- getAllUserIds userNames <- ZQuery.foreachPar(userIds)(getUserNameById) } yield userNames
  • 33. ZQUERY BENEFITS > parallelize queries > cache identical queries (deduplication) > batch queries if batching function provided
  • 34. ZQUERY > courtesy of @adamgfraser > based on paper on Haxl > "There is no Fork: An Abstraction for Efficient, Concurrent, and Concise Data Access" > will be extracted to its own library at some point
  • 35. INTROSPECTION Dogfooding case class __Introspection( __schema: __Schema, __type: __TypeArgs => __Type)
  • 36. USAGE 1. Define your queries / mutations / subscriptions 2. Provide a Schema for custom types 3. Provide a resolver 4. Profit
  • 37. 1. DEFINE YOUR QUERIES case class Pug(name: String, nicknames: List[String], favoriteFood: Option[String]) case class PugName(name: NonEmptyString) case class Queries(pugs: Task[List[Pug]], pug: PugName => Task[Pug]) type Pug { name: String! nicknames: [String!]! favoriteFood: String } type Queries { pugs: [Pug!] pug(name: String!): Pug }
  • 38. 2. PROVIDE A SCHEMA FOR CUSTOM TYPES implicit val nesSchema: Schema[NonEmptyString] = Schema.stringSchema.contramap(_.value)
  • 39. 3. PROVIDE A RESOLVER def getPugs: Task[List[Pug]] = ??? def getPug(name: String): Task[Pug] = ??? val queries = Queries( getPugs, args => getPug(args.name)) val resolver = RootResolver(queries)
  • 40. 4. PROFIT val interpreter = graphQL(resolver) for { result <- interpreter.execute(query) _ <- zio.console.putStrLn(result.toString) } yield ()
  • 41. HTTP4S MODULE val route: HttpRoutes[RIO[R, *]] = Http4sAdapter.makeRestService(interpreter) val wsRoute: HttpRoutes[RIO[R, *]] = Http4sAdapter.makeWebSocketService(interpreter)
  • 42. SCALAJS Few and modern dependencies ScalaJS support for free
  • 43. CATS COMPATIBILITY caliban-cats module def executeAsync[F[_]: Async](...)( implicit runtime: Runtime[Any]): F[GraphQLResponse[E]] def makeRestServiceF[F[_]: Effect, Q, M, S, E](...)( implicit runtime: Runtime[Any]): HttpRoutes[F]
  • 44. PERFORMANCE Caliban is fast Check benchmarks module on github
  • 45. FUTURE > Query analysis > Middleware (query-level, field-level) > Code generation > Other HTTP adapters (Akka HTTP) <- help needed > Client support
  • 46. WANNA KNOW MORE? > Website: https://ghostdogpr.github.io/caliban/ > ZIO Discord: #caliban