SlideShare uma empresa Scribd logo
1 de 17
Baixar para ler offline
Finch.io 
Purely Functional REST API 
with Finagle 
Vladimir Kostyukov 
http://vkostyukov.ru
http://github.com/finagle/finch 
2
Finch.io: Quickstart 
1 def hello(name: String) = new Service[HttpRequest, HttpResponse] = { 
2 def apply(req: HttpRequest) = for { 
3 title <- OptionalParam("title")(req) 
4 } yield Ok(s"Hello, ${title.getOrElse("")} $name!") 
5 } 
6 
7 val endpoint = new Endpoint[HttpRequest, HttpResponse] { 
8 def route = { 
9 // routes requests like '/hello/Bob?title=Mr.' 
10 case Method.Get -> Root / "hello" / name => hello(name) 
11 } 
12 } 
3
Finch.io Overview 
• Composable Endpoints 
• Composable Microservices 
• Request Reader 
• Response Builder 
• JSON 
• OAuth2, Basic Auth 
4
Endpoints 
1 val a = new Endpoint[HttpRequest, HttpResponse] { 
2 def route = { 
3 case Method.Get -> Root / "bob" => Redirect("/users/bob") 
4 case Method.Get -> Root / "users" / Long(id) => GetUser(id) 
5 } 
6 } 
7 
8 val b = new Endpoint[HttpRequest, HttpResponse] { 
9 def route = { 
10 case Method.Get -> Root / "tickets" => GetTickets 
11 } 
12 } 
13 
14 val c: Endpoint[HttpRequest, HttpResponse] = a orElse b 
15 val d: Service[HttpRequest, HttpResponse] = c.toService 
5
Composing services & endpoints 
1 val ab: Filter[A, C, B, C] = ??? 
2 val bc: Endpoint[B, C] = ??? 
3 val cd: Service[C, D] = ??? 
4 
5 val ad: Endpoint[A, D] = ab ! bc ! cd 
6
Case Study: Feedbacks Endpoint 
1 object Feedback extends Endpoint[OAuth2Request[OAuthUser], JsonResponse] { 
2 def route = { 
3 case Method.Get -> Root / "users" / Long(id) / "feedbacks" => 
4 GetUserFeedbacks(id) ! 
5 JoinInnerArrays("attachments") ! 
6 TakeAll 
7 
8 case Method.Put -> Root / "orders" / Long(id) / "feedback" => 
9 ByUserId(MakeSureUserCanPutOrderFeedback(_, id)) ! 
10 MakeSureThereIsNoOrderFeedbacks(id) ! 
11 MakeSureOrderIsCompleted(id) ! 
12 PutOrderFeedback(id) ! 
13 ByLocation(UpdateServiceRating) ! 
14 ByLocation(SendFeedbackSubmittedMail) ! 
15 ByLocation(GetFeedback) ! 
16 TakeFirst 
17 } 
18 } 
7
Params (Reader Monad) 
1 val user = for { 
2 name <- RequiredParam("name") 
3 age <- RequiredIntParam("age") 
4 city <- OptionalParam("city") 
5 } yield User(name, age, city.getOrElse("Novosibirsk")) 
6 
7 val service = new Service[HttpRequest, JsonResponse] { 
8 def apply(req: HttpRequest) = for { 
9 u <- user(req) 
10 } yield JsonObject( 
11 "name" -> u.name, 
12 "age" -> u.age, 
13 "city" -> u.city 
14 ) 
15 } 
16 
17 val u: Future[User] = user(request) handle { 
18 case e: ParamNotFound => BadRequest(e.param) 
19 } 
8
Case Study: Pagination 
1 val pagination = { 
2 val outerLimit = Config[Int]("limit", 15) 
3 
4 for { 
5 offset <- OptionalIntParam("offset") 
6 limit <- OptionalIntParam("limit") 
7 } yield ( 
8 offset.getOrElse(0), 
9 math.min(limit.getOrElse(outerLimit), outerLimit) 
10 ) 
11 } 
12 
13 val a = new Service[HttpRequest, HttpResponse] { 
14 def apply(req: HttpRequest) = for { 
15 (offset, limit) <- pagination(req) 
16 } yield Ok(s"offset $offset, limit $limit") 
17 } 
9
Multi-Value Params 
1 val reader = for { 
2 a <- RequiredIntParams("a") 
3 b <- RequiredIntParams("b") 
4 } yield (a, b) 
5 
6 // request("a=1,2,3&b=4&b=5") 
7 val (a, b): (List[Int], List[Int]) = reader(request) 
8 // a = List(1, 2, 3) 
9 // b = List(4, 5) 
10
Validation 
1 val adult = for { 
2 u <- user 
3 _ <- ValidationRule("age", "should be greater then 18") { user.age >= 18 } 
4 } yield u 
5 
6 val user: Future[User] = adult(request) handle { 
7 case e: ParamNotFound => 
8 BadRequest(JsonObject("param" -> e.param)) 
9 case e: ValidationFailed => 
10 BadRequest(JsonObject("param" -> e.param, "rule" -> e.rule)) 
11 } 
11
Responses 
1 // an empty response with status 200 
2 val a = Ok() 
3 
4 // 'plain/text' response with status 404 
5 val b = NotFound("body") 
6 
7 // 'application/json' response with status 201 
8 val c = Created(JsonObject("id" -> 42)) 
9 
10 // 'plain/text' response of status 403 with custom header 
11 val d = Forbidden.withHeaders("Some-Header-A" -> "a")("plain") 
12
JSON 
1 // a : { 
2 // b : 10, 
3 // c : 20, 
4 // d : 30 
5 // } 
6 val a = JsonObject("a.b" -> 10, "a.c" -> 20, "a.d" -> 30) 
7 
8 // a : { 
9 // a : 100, 
10 // b : 200 
11 // } 
12 val b = JsonObject("a.a" -> 100, "a.b" -> 200) 
13 
14 // a : { 
15 // a : 100 
16 // b : 200, 
17 // c : 20, 
18 // d : 30 
19 // } 
20 val c = JsonObject.mergeRight(a, b) 
13
Basic Auth 
1 object ProtectedUser extends Endpoint[HttpRequest, HttpResponse] { 
2 def route = { 
3 case Method.Get -> Root / "users" => 
4 BasicallyAuthorize("user", "password") ! 
5 GetUsers 
6 } 
7 } 
14
Further Steps 
• Lightweight in-memory caching 
• Better JSON 
15
References 
§ http://twitter.github.io/finagle/ 
! 
§ https://github.com/finagle/finch 
! 
§ https://github.com/finagle/finagle-oauth2 
16
Stay Finagled! 
! 
And drop your feedbacks to 
@vkostyukov 
17

Mais conteúdo relacionado

Mais procurados

Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & CollectionsCocoaHeads France
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2Jeado Ko
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Tsuyoshi Yamamoto
 
Tools for Solving Performance Issues
Tools for Solving Performance IssuesTools for Solving Performance Issues
Tools for Solving Performance IssuesOdoo
 
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Susan Potter
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetCocoaHeads France
 
Python meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OPython meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OBuzzcapture
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with JasmineLeon van der Grient
 
Flamingo Training - Hello World
Flamingo Training - Hello WorldFlamingo Training - Hello World
Flamingo Training - Hello Worldi-love-flamingo
 
PyCon lightning talk on my Toro module for Tornado
PyCon lightning talk on my Toro module for TornadoPyCon lightning talk on my Toro module for Tornado
PyCon lightning talk on my Toro module for Tornadoemptysquare
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHPThomas Weinert
 
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! GrailsプラグインTsuyoshi Yamamoto
 
2016 gunma.web games-and-asm.js
2016 gunma.web games-and-asm.js2016 gunma.web games-and-asm.js
2016 gunma.web games-and-asm.jsNoritada Shimizu
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaFlorent Pillet
 
Decoupling Objects With Standard Interfaces
Decoupling Objects With Standard InterfacesDecoupling Objects With Standard Interfaces
Decoupling Objects With Standard InterfacesThomas Weinert
 
Template syntax in Angular 2.0
Template syntax in Angular 2.0Template syntax in Angular 2.0
Template syntax in Angular 2.0Eyal Vardi
 
Using Cerberus and PySpark to validate semi-structured datasets
Using Cerberus and PySpark to validate semi-structured datasetsUsing Cerberus and PySpark to validate semi-structured datasets
Using Cerberus and PySpark to validate semi-structured datasetsBartosz Konieczny
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3Nate Abele
 

Mais procurados (20)

Swift Sequences & Collections
Swift Sequences & CollectionsSwift Sequences & Collections
Swift Sequences & Collections
 
Reactive, component 그리고 angular2
Reactive, component 그리고  angular2Reactive, component 그리고  angular2
Reactive, component 그리고 angular2
 
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
Grails 1.2 探検隊 -新たな聖杯をもとめて・・・-
 
React for Beginners
React for BeginnersReact for Beginners
React for Beginners
 
Tools for Solving Performance Issues
Tools for Solving Performance IssuesTools for Solving Performance Issues
Tools for Solving Performance Issues
 
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
Scalaz By Example (An IO Taster) -- PDXScala Meetup Jan 2014
 
Talk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe ConversetTalk KVO with rac by Philippe Converset
Talk KVO with rac by Philippe Converset
 
Python meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/OPython meetup: coroutines, event loops, and non-blocking I/O
Python meetup: coroutines, event loops, and non-blocking I/O
 
Testing Backbone applications with Jasmine
Testing Backbone applications with JasmineTesting Backbone applications with Jasmine
Testing Backbone applications with Jasmine
 
Flamingo Training - Hello World
Flamingo Training - Hello WorldFlamingo Training - Hello World
Flamingo Training - Hello World
 
PyCon lightning talk on my Toro module for Tornado
PyCon lightning talk on my Toro module for TornadoPyCon lightning talk on my Toro module for Tornado
PyCon lightning talk on my Toro module for Tornado
 
Asynchronous I/O in PHP
Asynchronous I/O in PHPAsynchronous I/O in PHP
Asynchronous I/O in PHP
 
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
第4回 g* ワークショップ はじめてみよう! Grailsプラグイン
 
2016 gunma.web games-and-asm.js
2016 gunma.web games-and-asm.js2016 gunma.web games-and-asm.js
2016 gunma.web games-and-asm.js
 
20151224-games
20151224-games20151224-games
20151224-games
 
Introduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoaIntroduction to reactive programming & ReactiveCocoa
Introduction to reactive programming & ReactiveCocoa
 
Decoupling Objects With Standard Interfaces
Decoupling Objects With Standard InterfacesDecoupling Objects With Standard Interfaces
Decoupling Objects With Standard Interfaces
 
Template syntax in Angular 2.0
Template syntax in Angular 2.0Template syntax in Angular 2.0
Template syntax in Angular 2.0
 
Using Cerberus and PySpark to validate semi-structured datasets
Using Cerberus and PySpark to validate semi-structured datasetsUsing Cerberus and PySpark to validate semi-structured datasets
Using Cerberus and PySpark to validate semi-structured datasets
 
Practical PHP 5.3
Practical PHP 5.3Practical PHP 5.3
Practical PHP 5.3
 

Semelhante a Finch.io - Purely Functional REST API with Finagle

Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveJeff Smith
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web developmentJohannes Brodwall
 
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + BallerinaWSO2
 
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiMonitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiInfluxData
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On RailsJohn Wilker
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platformsAyush Sharma
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on AndroidSven Haiges
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기Juwon Kim
 
ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...
ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...
ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...DynamicInfraDays
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Codestasimus
 
Top 10 F5 iRules to migrate to a modern load balancing platform
Top 10 F5 iRules to migrate to a modern load balancing platformTop 10 F5 iRules to migrate to a modern load balancing platform
Top 10 F5 iRules to migrate to a modern load balancing platformAvi Networks
 
Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發HO-HSUN LIN
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networkingVitali Pekelis
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代Shengyou Fan
 
Rpi python web
Rpi python webRpi python web
Rpi python websewoo lee
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Ismael Celis
 

Semelhante a Finch.io - Purely Functional REST API with Finagle (20)

Tools for Making Machine Learning more Reactive
Tools for Making Machine Learning more ReactiveTools for Making Machine Learning more Reactive
Tools for Making Machine Learning more Reactive
 
Bare-knuckle web development
Bare-knuckle web developmentBare-knuckle web development
Bare-knuckle web development
 
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
[WSO2 Integration Summit Madrid 2019] Integration + Ballerina
 
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry PiMonitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
Monitoring Your ISP Using InfluxDB Cloud and Raspberry Pi
 
I Phone On Rails
I Phone On RailsI Phone On Rails
I Phone On Rails
 
Flask and Angular: An approach to build robust platforms
Flask and Angular:  An approach to build robust platformsFlask and Angular:  An approach to build robust platforms
Flask and Angular: An approach to build robust platforms
 
CouchDB on Android
CouchDB on AndroidCouchDB on Android
CouchDB on Android
 
RESTful API 제대로 만들기
RESTful API 제대로 만들기RESTful API 제대로 만들기
RESTful API 제대로 만들기
 
ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...
ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...
ContainerDays NYC 2016: "OpenWhisk: A Serverless Computing Platform" (Rodric ...
 
Groovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony CodeGroovy vs Boilerplate and Ceremony Code
Groovy vs Boilerplate and Ceremony Code
 
Top 10 F5 iRules to migrate to a modern load balancing platform
Top 10 F5 iRules to migrate to a modern load balancing platformTop 10 F5 iRules to migrate to a modern load balancing platform
Top 10 F5 iRules to migrate to a modern load balancing platform
 
Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發Chaincode Development 區塊鏈鏈碼開發
Chaincode Development 區塊鏈鏈碼開發
 
Advanced #2 networking
Advanced #2   networkingAdvanced #2   networking
Advanced #2 networking
 
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
[JCConf 2020] 用 Kotlin 跨入 Serverless 世代
 
Rpi python web
Rpi python webRpi python web
Rpi python web
 
Intro to Sail.js
Intro to Sail.jsIntro to Sail.js
Intro to Sail.js
 
Server Side Swift: Vapor
Server Side Swift: VaporServer Side Swift: Vapor
Server Side Swift: Vapor
 
Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010Websockets talk at Rubyconf Uruguay 2010
Websockets talk at Rubyconf Uruguay 2010
 
Android dev 3
Android dev 3Android dev 3
Android dev 3
 
Ajax - a quick introduction
Ajax - a quick introductionAjax - a quick introduction
Ajax - a quick introduction
 

Último

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demoHarshalMandlekar2
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Mark Goldstein
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterMydbops
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxLoriGlavin3
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxLoriGlavin3
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI AgeCprime
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsRavi Sanghani
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPathCommunity
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024Lonnie McRorey
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfIngrid Airi González
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxLoriGlavin3
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxLoriGlavin3
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditSkynet Technologies
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfpanagenda
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxLoriGlavin3
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Strongerpanagenda
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity PlanDatabarracks
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024BookNet Canada
 

Último (20)

TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data PrivacyTrustArc Webinar - How to Build Consumer Trust Through Data Privacy
TrustArc Webinar - How to Build Consumer Trust Through Data Privacy
 
Sample pptx for embedding into website for demo
Sample pptx for embedding into website for demoSample pptx for embedding into website for demo
Sample pptx for embedding into website for demo
 
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
Arizona Broadband Policy Past, Present, and Future Presentation 3/25/24
 
Scale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL RouterScale your database traffic with Read & Write split using MySQL Router
Scale your database traffic with Read & Write split using MySQL Router
 
The State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptxThe State of Passkeys with FIDO Alliance.pptx
The State of Passkeys with FIDO Alliance.pptx
 
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptxA Deep Dive on Passkeys: FIDO Paris Seminar.pptx
A Deep Dive on Passkeys: FIDO Paris Seminar.pptx
 
A Framework for Development in the AI Age
A Framework for Development in the AI AgeA Framework for Development in the AI Age
A Framework for Development in the AI Age
 
Potential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and InsightsPotential of AI (Generative AI) in Business: Learnings and Insights
Potential of AI (Generative AI) in Business: Learnings and Insights
 
UiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to HeroUiPath Community: Communication Mining from Zero to Hero
UiPath Community: Communication Mining from Zero to Hero
 
TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024TeamStation AI System Report LATAM IT Salaries 2024
TeamStation AI System Report LATAM IT Salaries 2024
 
Generative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdfGenerative Artificial Intelligence: How generative AI works.pdf
Generative Artificial Intelligence: How generative AI works.pdf
 
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptxMerck Moving Beyond Passwords: FIDO Paris Seminar.pptx
Merck Moving Beyond Passwords: FIDO Paris Seminar.pptx
 
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptxPasskey Providers and Enabling Portability: FIDO Paris Seminar.pptx
Passkey Providers and Enabling Portability: FIDO Paris Seminar.pptx
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
Manual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance AuditManual 508 Accessibility Compliance Audit
Manual 508 Accessibility Compliance Audit
 
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdfSo einfach geht modernes Roaming fuer Notes und Nomad.pdf
So einfach geht modernes Roaming fuer Notes und Nomad.pdf
 
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptxDigital Identity is Under Attack: FIDO Paris Seminar.pptx
Digital Identity is Under Attack: FIDO Paris Seminar.pptx
 
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better StrongerModern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
Modern Roaming for Notes and Nomad – Cheaper Faster Better Stronger
 
How to write a Business Continuity Plan
How to write a Business Continuity PlanHow to write a Business Continuity Plan
How to write a Business Continuity Plan
 
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
New from BookNet Canada for 2024: Loan Stars - Tech Forum 2024
 

Finch.io - Purely Functional REST API with Finagle

  • 1. Finch.io Purely Functional REST API with Finagle Vladimir Kostyukov http://vkostyukov.ru
  • 3. Finch.io: Quickstart 1 def hello(name: String) = new Service[HttpRequest, HttpResponse] = { 2 def apply(req: HttpRequest) = for { 3 title <- OptionalParam("title")(req) 4 } yield Ok(s"Hello, ${title.getOrElse("")} $name!") 5 } 6 7 val endpoint = new Endpoint[HttpRequest, HttpResponse] { 8 def route = { 9 // routes requests like '/hello/Bob?title=Mr.' 10 case Method.Get -> Root / "hello" / name => hello(name) 11 } 12 } 3
  • 4. Finch.io Overview • Composable Endpoints • Composable Microservices • Request Reader • Response Builder • JSON • OAuth2, Basic Auth 4
  • 5. Endpoints 1 val a = new Endpoint[HttpRequest, HttpResponse] { 2 def route = { 3 case Method.Get -> Root / "bob" => Redirect("/users/bob") 4 case Method.Get -> Root / "users" / Long(id) => GetUser(id) 5 } 6 } 7 8 val b = new Endpoint[HttpRequest, HttpResponse] { 9 def route = { 10 case Method.Get -> Root / "tickets" => GetTickets 11 } 12 } 13 14 val c: Endpoint[HttpRequest, HttpResponse] = a orElse b 15 val d: Service[HttpRequest, HttpResponse] = c.toService 5
  • 6. Composing services & endpoints 1 val ab: Filter[A, C, B, C] = ??? 2 val bc: Endpoint[B, C] = ??? 3 val cd: Service[C, D] = ??? 4 5 val ad: Endpoint[A, D] = ab ! bc ! cd 6
  • 7. Case Study: Feedbacks Endpoint 1 object Feedback extends Endpoint[OAuth2Request[OAuthUser], JsonResponse] { 2 def route = { 3 case Method.Get -> Root / "users" / Long(id) / "feedbacks" => 4 GetUserFeedbacks(id) ! 5 JoinInnerArrays("attachments") ! 6 TakeAll 7 8 case Method.Put -> Root / "orders" / Long(id) / "feedback" => 9 ByUserId(MakeSureUserCanPutOrderFeedback(_, id)) ! 10 MakeSureThereIsNoOrderFeedbacks(id) ! 11 MakeSureOrderIsCompleted(id) ! 12 PutOrderFeedback(id) ! 13 ByLocation(UpdateServiceRating) ! 14 ByLocation(SendFeedbackSubmittedMail) ! 15 ByLocation(GetFeedback) ! 16 TakeFirst 17 } 18 } 7
  • 8. Params (Reader Monad) 1 val user = for { 2 name <- RequiredParam("name") 3 age <- RequiredIntParam("age") 4 city <- OptionalParam("city") 5 } yield User(name, age, city.getOrElse("Novosibirsk")) 6 7 val service = new Service[HttpRequest, JsonResponse] { 8 def apply(req: HttpRequest) = for { 9 u <- user(req) 10 } yield JsonObject( 11 "name" -> u.name, 12 "age" -> u.age, 13 "city" -> u.city 14 ) 15 } 16 17 val u: Future[User] = user(request) handle { 18 case e: ParamNotFound => BadRequest(e.param) 19 } 8
  • 9. Case Study: Pagination 1 val pagination = { 2 val outerLimit = Config[Int]("limit", 15) 3 4 for { 5 offset <- OptionalIntParam("offset") 6 limit <- OptionalIntParam("limit") 7 } yield ( 8 offset.getOrElse(0), 9 math.min(limit.getOrElse(outerLimit), outerLimit) 10 ) 11 } 12 13 val a = new Service[HttpRequest, HttpResponse] { 14 def apply(req: HttpRequest) = for { 15 (offset, limit) <- pagination(req) 16 } yield Ok(s"offset $offset, limit $limit") 17 } 9
  • 10. Multi-Value Params 1 val reader = for { 2 a <- RequiredIntParams("a") 3 b <- RequiredIntParams("b") 4 } yield (a, b) 5 6 // request("a=1,2,3&b=4&b=5") 7 val (a, b): (List[Int], List[Int]) = reader(request) 8 // a = List(1, 2, 3) 9 // b = List(4, 5) 10
  • 11. Validation 1 val adult = for { 2 u <- user 3 _ <- ValidationRule("age", "should be greater then 18") { user.age >= 18 } 4 } yield u 5 6 val user: Future[User] = adult(request) handle { 7 case e: ParamNotFound => 8 BadRequest(JsonObject("param" -> e.param)) 9 case e: ValidationFailed => 10 BadRequest(JsonObject("param" -> e.param, "rule" -> e.rule)) 11 } 11
  • 12. Responses 1 // an empty response with status 200 2 val a = Ok() 3 4 // 'plain/text' response with status 404 5 val b = NotFound("body") 6 7 // 'application/json' response with status 201 8 val c = Created(JsonObject("id" -> 42)) 9 10 // 'plain/text' response of status 403 with custom header 11 val d = Forbidden.withHeaders("Some-Header-A" -> "a")("plain") 12
  • 13. JSON 1 // a : { 2 // b : 10, 3 // c : 20, 4 // d : 30 5 // } 6 val a = JsonObject("a.b" -> 10, "a.c" -> 20, "a.d" -> 30) 7 8 // a : { 9 // a : 100, 10 // b : 200 11 // } 12 val b = JsonObject("a.a" -> 100, "a.b" -> 200) 13 14 // a : { 15 // a : 100 16 // b : 200, 17 // c : 20, 18 // d : 30 19 // } 20 val c = JsonObject.mergeRight(a, b) 13
  • 14. Basic Auth 1 object ProtectedUser extends Endpoint[HttpRequest, HttpResponse] { 2 def route = { 3 case Method.Get -> Root / "users" => 4 BasicallyAuthorize("user", "password") ! 5 GetUsers 6 } 7 } 14
  • 15. Further Steps • Lightweight in-memory caching • Better JSON 15
  • 16. References § http://twitter.github.io/finagle/ ! § https://github.com/finagle/finch ! § https://github.com/finagle/finagle-oauth2 16
  • 17. Stay Finagled! ! And drop your feedbacks to @vkostyukov 17