SlideShare a Scribd company logo
CALIBAN
FUNCTIONAL GRAPHQL LIBRARY FOR SCALA
Scala Matsuri - October 2020
Scalaの GraphQLライブラリ
WHO AM I?
> Pierre Ricadat aka @ghostdogpr
>
!
exiled to
"
> Developer at devsisters
> Contributor to ZIO
> Creator of Caliban
自己紹介
フランス出身韓
Caliban作者
GRAPHQL ?
GraphQLとは?
GRAPHQL IN A NUTSHELL
> query language for APIs
> server exposes a typed schema
> client requests and receives only what they want
> client and server can use any programming language
> good tooling
GraphQLの
API のためのクエリ言語、スキーマは型付き
GRAPHQL SCHEMA
type Query {
user(id: ID): User
users: [User!]!
}
type User {
id: ID!
name: String!
age: Int
}
GraphQLスキーマ
GRAPHQL QUERY
query {
user(id: "xxx") {
name
age
}
}
GraphQLクエリ
GRAPHQL IN SCALA
> Sangria
> Caliban
> server
> client (including Scala.js support)
ScalaのGraphQLライブラリ
MOTIVATIONS
> minimize boilerplate
> purely functional
> strongly typed
> explicit errors
> user friendly
動機
ボイラープレートの最小化 / 純
DEFINING A SCHEMA
case class User(
id: UUID,
name: String,
age: Option[Int]
)
type User {
id: ID!
name: String!
age: Int
}
スキーマ定義
DEFINING A SCHEMA
case class UserArgs(id: UUID)
case class Query (
user: UserArgs => Option[User]
users: List[User]
)
type Query {
user(id: ID): User
users: [User!]!
}
スキーマ定義
SUPPORTED SCHEMAS
> Int, String, Boolean, List, Option, Tuple...
> Java Time, Java UUID
> Future, ZIO, ZStream
> case classes, sealed traits (derived by Magnolia)
> Monix, Cats Effect, Circe, Refined (via interop)
サポートしているスキーマ
各種基本の型、ライブラリに加え、自分でも
DEFINING A RESOLVER
val query = Query(
args => userService.getUser(args.id),
userService.getAllUsers
)
val api = graphQL(RootResolver(query))
リゾルバーの定義
CHECK YOUR SCHEMA
println(api.render)
/**
type Query {
user(id: ID): User
users: [User!]!
}
type User {
id: ID!
name: String!
age: Int
}
**/
スキーマを表示確認
TEST YOUR API
val query = "query { user(id: "xxx") { name age } }"
for {
interpreter <- api.interpreter
result <- interpreter.execute(query)
} yield result
APIをテストする
SERVE YOUR API
> http4s
> Akka HTTP
> Play Framework
> Finch
val route: HttpRoutes[Task] = Http4sAdapter.makeHttpService(interpreter)
APIをサーバーで動かす
N + 1 PROBLEM
query {
order(id: 12345) {
name
products {
name
}
}
}
NAIVE
for {
order <- getOrder(id)
products <- ZIO.foreachPar(order.pIds)(getProduct)
} yield Order(order.name, products)
n + 1 requests
そのままだと・・・
N+1回のリクエスト
OPTIMIZED
for {
order <- getOrder(id)
products <- ZQuery.foreachPar(order.pIds)(getProduct)
} yield Order(order.name, products)
2 requests
最適化すると
2回のリクエスト
ZQUERY
case class GetProduct(id: Int) extends Request[Throwable, Product]
val ProductDataSource =
DataSource.fromFunctionBatchedM("ProductDataSource")(
requests => dbService.getProducts(requests.map(_.id))
)
def getProduct(id: Int): ZQuery[Any, Throwable, Product] =
ZQuery.fromRequest(GetProduct(id))(ProductDataSource)
> See zio-query
ZQueryを使うと
WRAPPERS
> parsing
> validation
> execution
> field execution
> whole execution
ラッパー
パース、
BUILTIN WRAPPERS
val api = graphQL(...) @@
maxDepth(30) @@
maxFields(200) @@
timeout(10 seconds) @@
printSlowQueries(1 second)
> Apollo Tracing, Apollo Caching, Apollo Persisted
Queries, etc.
組み
Apolloのトレース、キャシュ、永
MORE FEATURES
> combine APIs
> annotations
> code generation tool
> schema diff
> Apollo Federation
他の機能
APIの結合、アノテーション、コード生成ツール等
CALIBAN CLIENT
> no boilerplate
> no more string copy-pasting
> no need for aliases, fragments, etc
Calibanクライアント
無ボイラープレート、alias や fragment もいらない
STEP 1: CODEGEN TOOL
calibanGenClient <schemaPath> <outputPath>
type Location {
latitude: Float!
longitude: Float!
}
⬇
type Location
object Location {
def latitude: SelectionBuilder[Location, Double] = (...)
def longitude: SelectionBuilder[Location, Double] = (...)
}
コード生成ツール
STEP 2: WRITING QUERIES
val location =
Location.latitude ~ Location.longitude
val query =
Query.search(Some("Berlin Ostbahnhof")) {
Searchable.stations {
Station.name ~ Station.location {
location
}
}
}
クエリを書く
STEP 3: RUNNING QUERIES
val request = query.toRequest(uri)
SttpClient.send(request)
> Response is already parsed into Scala types
> Use the sttp backend of your choice (including Scala.js)
クエリの
レスポンスはScalaの型としてパース /Scala.jsを含み、
好きなsttpバックエンドを使用可能
CURRENT STATE
> Recently celebrated 1st birthday
> Already 520 stars on github
> Built by 45 contributors
#
現在の
開 1年 /520スター/45コントリビューター/パフォーマ
ンス改善
THANKS!
> Website: https://ghostdogpr.github.io/caliban/
> Resources, FAQ, Examples
> ZIO Discord: #caliban
> Twitter: @ghostdogpr
ご
QUESTIONS?
質問はありますか?

More Related Content

PPTX
[OOP - Lec 08] Encapsulation (Information Hiding)
PDF
Functional Domain Modeling - The ZIO 2 Way
PDF
Java collections
PDF
Java ArrayList Tutorial | Edureka
PPTX
Constructor in java
PPT
Ooad sequence diagram lecture
PPTX
Method Overloading in Java
PPTX
Collections framework in java
[OOP - Lec 08] Encapsulation (Information Hiding)
Functional Domain Modeling - The ZIO 2 Way
Java collections
Java ArrayList Tutorial | Edureka
Constructor in java
Ooad sequence diagram lecture
Method Overloading in Java
Collections framework in java

What's hot (20)

PPSX
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
PPTX
Introduction to OOP(in java) BY Govind Singh
PPT
List in java
PPTX
Templates in C++
PDF
ZIO-Direct - Functional Scala 2022
ODP
Java Collections
PPTX
Object Oriented Programming In JavaScript
PPTX
Clases abstractas e interfaces (AlexandraPerez)
PDF
Generics
PPTX
collection framework in java
PPTX
Javascript this keyword
PPTX
Java packages
PPTX
Access modifiers in java
PDF
5 collection framework
PPTX
Java Foundations: Data Types and Type Conversion
PPT
recursion.ppt
PPTX
Presentation1
PPTX
PDF
Corso Java 1 - BASE
Spring - Part 2 - Autowiring, Annotations, Java based Configuration - slides
Introduction to OOP(in java) BY Govind Singh
List in java
Templates in C++
ZIO-Direct - Functional Scala 2022
Java Collections
Object Oriented Programming In JavaScript
Clases abstractas e interfaces (AlexandraPerez)
Generics
collection framework in java
Javascript this keyword
Java packages
Access modifiers in java
5 collection framework
Java Foundations: Data Types and Type Conversion
recursion.ppt
Presentation1
Corso Java 1 - BASE
Ad

Similar to Caliban: Functional GraphQL Library for Scala (20)

PDF
GraphQL with scala
PDF
めんどくさくない Scala #kwkni_scala
PDF
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
PDF
GraphQLはどんな時に使うか
PDF
Introduction to Spray at Kansai Functional Programming
PDF
20241114_flutter_tokyo_flutter_graphql_usequery.pdf
PDF
実務者のためのかんたんScalaz
PDF
Scalaでのプログラム開発
PDF
Play framework 2.0のちょっとした紹介
PDF
Scala超入門 - 2014/12/13 Scala関西勉強会
PDF
Clojure
PDF
ATN No.2 Scala事始め
PDF
20120423 hbase勉強会
PDF
GraphQL入門
PDF
GraphQLおよびそのエコシステム解説とチュートリアル紹介のためのプレゼンテーション資料
PDF
ScalaでAndroidアプリ開発
PDF
Scala EE 7 Essentials
PPTX
実践!Django + GraphQL 実装
PDF
Java ee6 with scala
PDF
GraphQL超入門(座学).pdf
GraphQL with scala
めんどくさくない Scala #kwkni_scala
インターフェース定義言語から学ぶモダンなWeb API方式: REST, GraphQL, gRPC
GraphQLはどんな時に使うか
Introduction to Spray at Kansai Functional Programming
20241114_flutter_tokyo_flutter_graphql_usequery.pdf
実務者のためのかんたんScalaz
Scalaでのプログラム開発
Play framework 2.0のちょっとした紹介
Scala超入門 - 2014/12/13 Scala関西勉強会
Clojure
ATN No.2 Scala事始め
20120423 hbase勉強会
GraphQL入門
GraphQLおよびそのエコシステム解説とチュートリアル紹介のためのプレゼンテーション資料
ScalaでAndroidアプリ開発
Scala EE 7 Essentials
実践!Django + GraphQL 実装
Java ee6 with scala
GraphQL超入門(座学).pdf
Ad

Caliban: Functional GraphQL Library for Scala

  • 1. CALIBAN FUNCTIONAL GRAPHQL LIBRARY FOR SCALA Scala Matsuri - October 2020 Scalaの GraphQLライブラリ
  • 2. WHO AM I? > Pierre Ricadat aka @ghostdogpr > ! exiled to " > Developer at devsisters > Contributor to ZIO > Creator of Caliban 自己紹介 フランス出身韓 Caliban作者
  • 4. GRAPHQL IN A NUTSHELL > query language for APIs > server exposes a typed schema > client requests and receives only what they want > client and server can use any programming language > good tooling GraphQLの API のためのクエリ言語、スキーマは型付き
  • 5. GRAPHQL SCHEMA type Query { user(id: ID): User users: [User!]! } type User { id: ID! name: String! age: Int } GraphQLスキーマ
  • 6. GRAPHQL QUERY query { user(id: "xxx") { name age } } GraphQLクエリ
  • 7. GRAPHQL IN SCALA > Sangria > Caliban > server > client (including Scala.js support) ScalaのGraphQLライブラリ
  • 8. MOTIVATIONS > minimize boilerplate > purely functional > strongly typed > explicit errors > user friendly 動機 ボイラープレートの最小化 / 純
  • 9. DEFINING A SCHEMA case class User( id: UUID, name: String, age: Option[Int] ) type User { id: ID! name: String! age: Int } スキーマ定義
  • 10. DEFINING A SCHEMA case class UserArgs(id: UUID) case class Query ( user: UserArgs => Option[User] users: List[User] ) type Query { user(id: ID): User users: [User!]! } スキーマ定義
  • 11. SUPPORTED SCHEMAS > Int, String, Boolean, List, Option, Tuple... > Java Time, Java UUID > Future, ZIO, ZStream > case classes, sealed traits (derived by Magnolia) > Monix, Cats Effect, Circe, Refined (via interop) サポートしているスキーマ 各種基本の型、ライブラリに加え、自分でも
  • 12. DEFINING A RESOLVER val query = Query( args => userService.getUser(args.id), userService.getAllUsers ) val api = graphQL(RootResolver(query)) リゾルバーの定義
  • 13. CHECK YOUR SCHEMA println(api.render) /** type Query { user(id: ID): User users: [User!]! } type User { id: ID! name: String! age: Int } **/ スキーマを表示確認
  • 14. TEST YOUR API val query = "query { user(id: "xxx") { name age } }" for { interpreter <- api.interpreter result <- interpreter.execute(query) } yield result APIをテストする
  • 15. SERVE YOUR API > http4s > Akka HTTP > Play Framework > Finch val route: HttpRoutes[Task] = Http4sAdapter.makeHttpService(interpreter) APIをサーバーで動かす
  • 16. N + 1 PROBLEM query { order(id: 12345) { name products { name } } }
  • 17. NAIVE for { order <- getOrder(id) products <- ZIO.foreachPar(order.pIds)(getProduct) } yield Order(order.name, products) n + 1 requests そのままだと・・・ N+1回のリクエスト
  • 18. OPTIMIZED for { order <- getOrder(id) products <- ZQuery.foreachPar(order.pIds)(getProduct) } yield Order(order.name, products) 2 requests 最適化すると 2回のリクエスト
  • 19. ZQUERY case class GetProduct(id: Int) extends Request[Throwable, Product] val ProductDataSource = DataSource.fromFunctionBatchedM("ProductDataSource")( requests => dbService.getProducts(requests.map(_.id)) ) def getProduct(id: Int): ZQuery[Any, Throwable, Product] = ZQuery.fromRequest(GetProduct(id))(ProductDataSource) > See zio-query ZQueryを使うと
  • 20. WRAPPERS > parsing > validation > execution > field execution > whole execution ラッパー パース、
  • 21. BUILTIN WRAPPERS val api = graphQL(...) @@ maxDepth(30) @@ maxFields(200) @@ timeout(10 seconds) @@ printSlowQueries(1 second) > Apollo Tracing, Apollo Caching, Apollo Persisted Queries, etc. 組み Apolloのトレース、キャシュ、永
  • 22. MORE FEATURES > combine APIs > annotations > code generation tool > schema diff > Apollo Federation 他の機能 APIの結合、アノテーション、コード生成ツール等
  • 23. CALIBAN CLIENT > no boilerplate > no more string copy-pasting > no need for aliases, fragments, etc Calibanクライアント 無ボイラープレート、alias や fragment もいらない
  • 24. STEP 1: CODEGEN TOOL calibanGenClient <schemaPath> <outputPath> type Location { latitude: Float! longitude: Float! } ⬇ type Location object Location { def latitude: SelectionBuilder[Location, Double] = (...) def longitude: SelectionBuilder[Location, Double] = (...) } コード生成ツール
  • 25. STEP 2: WRITING QUERIES val location = Location.latitude ~ Location.longitude val query = Query.search(Some("Berlin Ostbahnhof")) { Searchable.stations { Station.name ~ Station.location { location } } } クエリを書く
  • 26. STEP 3: RUNNING QUERIES val request = query.toRequest(uri) SttpClient.send(request) > Response is already parsed into Scala types > Use the sttp backend of your choice (including Scala.js) クエリの レスポンスはScalaの型としてパース /Scala.jsを含み、 好きなsttpバックエンドを使用可能
  • 27. CURRENT STATE > Recently celebrated 1st birthday > Already 520 stars on github > Built by 45 contributors # 現在の 開 1年 /520スター/45コントリビューター/パフォーマ ンス改善
  • 28. THANKS! > Website: https://ghostdogpr.github.io/caliban/ > Resources, FAQ, Examples > ZIO Discord: #caliban > Twitter: @ghostdogpr ご