SlideShare a Scribd company logo
Finch + Finagle-OAuth2
=
Purely Functional REST API
Vladimir Kostyukov
@vkostyukov
Finagle-OAuth2: Highlights
• Asynchronous version of Nulab’s scala-oauth2-provider
!
• Finagle-friendly API: OAuth2Request, OAuth2Filter	
!
• Does not depend on Finch
2
1 trait DataHandler[U] {	
2 ... 	
3 def findUser(username: String, password: String): Future[Option[U]]	
4 def createAccessToken(authInfo: AuthInfo[U]): Future[AccessToken]	
5 def getStoredAccessToken(authInfo: AuthInfo[U]): Future[Option[AccessToken]]	
6 def findAccessToken(token: String): Future[Option[AccessToken]]	
7 ...	
8 }	
Finagle-OAuth2: Step #1
DataHandler
3
Finagle-OAuth2: Step #2
Typesafe Auth
1 import com.twitter.finagle.oauth2._	
2 import com.twitter.finagle.oauth2.{OAuth2Filter, OAuth2Request}	
3 	
4 val auth = new OAuth2Filter(dataHandler)	
5 	
6 val hello = new Service[OAuth2Request[User], Response] {	
7 def apply(req: OAuth2Request[User]) = {	
8 println(s"Hello, ${req.authInfo.user}!")	
9 Future.value(Response())	
10 }	
11 }	
12 	
13 val backend: Service[Request, Response] = auth andThen hello	
4
1 import com.twitter.finagle.oauth2._	
2 import com.twitter.finagle.oauth2.OAuth2Endpoint	
3 	
4 val tokens: Service[Request, Response] = 	
5 new OAuth2Endpoint(dataHandler) with OAuthErrorInJson with OAuthTokenInJson	
Finagle-OAuth2: Step #3
Issue Acces Token
5
Thin layer of purely-functional basic blocks
on top of Finagle for building composable
REST APIs
Finch
https://github.com/finagle/finch
6
Finch: Highlights
• Was #1 Scala trending repo on GitHub for 95 mins
!
!
!
!
!
!
!
• Happily used in production by 2 customers:
• Konfettin
• JusBrasil
!
• Super simple & lightweight (~ 1.5k SLOC)
7
Finch: 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 => 	
11 BasicallyAuthorize("user", "password") ! hello(name)	
12 }	
13 }	
14 	
15 val service: Service[HttpRequest, HttpResponse] = endpoint.toService 	
8
Finch: Request Reader
(Reader Monad)
1 trait RequestReader[A] {	
2 	
3 def apply(req: HttpRequest): Future[A]	
4 	
5 def flatMap[B](fn: A => RequestReader[B]): RequestReader[B] = ???	
6 	
7 def map[B](fn: A => B): RequestReader[B] = ???	
8 }	
9
Finch: Request Reader
1 val pagination: RequestReader[(Int, Int)] = for {	
2 offset <- OptionalIntParam("offset")	
3 limit <- OptionalIntParam("limit")	
4 } yield (offset.getOrElse(0), math.min(limit.getOrElse(50), 50))	
5 	
6 val service = new Service[HttpRequest, HttpResponse] {	
7 def apply(req: HttpRequest) = for {	
8 (offsetIt, limit) <- pagination(req)	
9 } yield Ok(s"Fetching items $offset..${offset+limit}")	
10 }	
10
Finch: Params Validation
1 case class User(age: Int)	
2 	
3 val user: RequestReader[User] = 	
4 for { age <- RequiredIntParam("age") } yield User(age)	
5 	
6 val adult: RequestReader[User] = for {	
7 u <- user	
8 _ <- ValidationRule("age", "should be greater then 18") { user.age > 18 }	
9 } yield u	
10 	
11 val u: Future[JsonResponse] = adult(request) map { 	
12 JsonObject("age" -> _.age) 	
13 } handle {	
14 case e: ParamNotFound =>	
15 JsonObject("error" -> e.getMessage, "param" -> e.param)	
16 case e: ValidationFailed => 	
17 JsonObject("error" -> e.getMessage, "param" -> e.param)	
18 }	
11
Finch:
Request Reader Highlights
• RequiredParam, RequiredIntParam, etc 	
• Future.value[A]	
• Future.exception[ParamNotFound]
!
• OptionalParam, OptionalIntParam, etc	
• Future.value[Option[A]]
!
• Multi-value Params: RequiredParams, OptionalIntParams, etc.
• Future.value[List[A]]
!
• Params Validation: ValidationRule	
• Future.value[Unit]	
• Future.exception[ValidationFailed]
12
Finch: Responses
1 // 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" -> 100))	
9 	
10 // ‘plain/text' response with custom header and status 403	
11 val d = Forbidden.withHeaders("Some-Header" -> "Secret")("body") 	
13
Finch: Endpoints Highlights
• Finch’s Endpoints are composable routers
!
• Endpoints might be treated as Scala’s
PartialFunctions[Request, Service[_, _]]
!
• Endpoints are convertible to Finagle Service’s
!
• Endpoints might be composed with Service’s, Filter’s or
other Endpoint’s.
14
Finch:
Endpoints Composition
1 val ab: Filter[A, C, B, C] = ???	
2 val bc: Endpoint[B, C] = ???	
3 val cd: Service[C, D]	
4 	
5 val ad1: Endpoint[A, D] = ab ! bc ! cd	
6 val ad2: Endpoint[A, D] = ???	
7 	
8 val ad3: Endpoint[A, D] = ad1 orElse ad2	
15
Finagle rocks!
16
• A better JSON
• Lightweight in-memory caching API
Finch: Further Steps
17
• https://github.com/finagle/finch
• https://github.com/finagle/finagle-oauth2
Resources
@vkostyukov
18

More Related Content

PDF
Async Microservices with Twitter's Finagle
PDF
Finch.io - Purely Functional REST API with Finagle
DOCX
Pratik Bakane C++
PDF
Un dsl pour ma base de données
DOCX
Pratik Bakane C++
PDF
DOCX
Pratik Bakane C++
PDF
Пишем для asyncio - Андрей Светлов, PyCon RU 2014
Async Microservices with Twitter's Finagle
Finch.io - Purely Functional REST API with Finagle
Pratik Bakane C++
Un dsl pour ma base de données
Pratik Bakane C++
Pratik Bakane C++
Пишем для asyncio - Андрей Светлов, PyCon RU 2014

What's hot (20)

PDF
2016 gunma.web games-and-asm.js
PDF
20151224-games
DOCX
Pratik Bakane C++
DOCX
Pratik Bakane C++
PDF
Introduction to Go for Java Programmers
PDF
The Ring programming language version 1.5.4 book - Part 40 of 185
PDF
Javascript compilation execution
PPT
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
PDF
PyCon lightning talk on my Toro module for Tornado
PDF
JavaSE7 Launch Event: Java7xGroovy
KEY
サイ本 文
PDF
Rntb20200805
 
PPTX
Guava - Elements of Functional Programming
PDF
Python meetup: coroutines, event loops, and non-blocking I/O
PDF
Mozilla とブラウザゲーム
PPTX
Queue oop
TXT
c++ project on restaurant billing
PDF
Tilting at Windmills with ctypes and cygwinreg
PDF
2016 gunma.web games-and-asm.js
20151224-games
Pratik Bakane C++
Pratik Bakane C++
Introduction to Go for Java Programmers
The Ring programming language version 1.5.4 book - Part 40 of 185
Javascript compilation execution
DATASTRUCTURES PPTS PREPARED BY M V BRAHMANANDA REDDY
PyCon lightning talk on my Toro module for Tornado
JavaSE7 Launch Event: Java7xGroovy
サイ本 文
Rntb20200805
 
Guava - Elements of Functional Programming
Python meetup: coroutines, event loops, and non-blocking I/O
Mozilla とブラウザゲーム
Queue oop
c++ project on restaurant billing
Tilting at Windmills with ctypes and cygwinreg
Ad

Similar to Finch + Finagle OAuth2 (20)

PPTX
Introduction to Finch
PDF
Julio Capote, Twitter
PDF
RESTful API using scalaz (3)
PDF
Scala.io
PDF
Dependency Injection in Functional Programming
PDF
Finatra v2
PPTX
Tools for Making Machine Learning more Reactive
PPTX
Exploring Twitter's Finagle technology stack for microservices
PDF
Principles of the Play framework
PDF
ScalaDays Amsterdam - Don't block yourself
PDF
"Scala in Goozy", Alexey Zlobin
PPTX
High Performance RPC with Finagle
PDF
From polling to real time: Scala, Akka, and Websockets from scratch
PDF
Event Sourcing and Functional Programming
PDF
Functional Programming & Event Sourcing - a pair made in heaven
PDF
Scala Frameworks for Web Application 2016
PPTX
Concurrent Application Development using Scala
PDF
Unfiltered Unveiled
PDF
Functional Systems @ Twitter
PDF
Finagle By Twitter Engineer @ Knoldus
Introduction to Finch
Julio Capote, Twitter
RESTful API using scalaz (3)
Scala.io
Dependency Injection in Functional Programming
Finatra v2
Tools for Making Machine Learning more Reactive
Exploring Twitter's Finagle technology stack for microservices
Principles of the Play framework
ScalaDays Amsterdam - Don't block yourself
"Scala in Goozy", Alexey Zlobin
High Performance RPC with Finagle
From polling to real time: Scala, Akka, and Websockets from scratch
Event Sourcing and Functional Programming
Functional Programming & Event Sourcing - a pair made in heaven
Scala Frameworks for Web Application 2016
Concurrent Application Development using Scala
Unfiltered Unveiled
Functional Systems @ Twitter
Finagle By Twitter Engineer @ Knoldus
Ad

Recently uploaded (20)

PPTX
OOP with Java - Java Introduction (Basics)
PPTX
additive manufacturing of ss316l using mig welding
PPTX
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
PDF
Digital Logic Computer Design lecture notes
PPTX
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
PPTX
Foundation to blockchain - A guide to Blockchain Tech
PDF
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
PDF
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
PPTX
CH1 Production IntroductoryConcepts.pptx
PPTX
UNIT 4 Total Quality Management .pptx
PPTX
CYBER-CRIMES AND SECURITY A guide to understanding
PDF
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
PPTX
Construction Project Organization Group 2.pptx
PDF
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
PPTX
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
PPTX
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
PPTX
Internet of Things (IOT) - A guide to understanding
PDF
Arduino robotics embedded978-1-4302-3184-4.pdf
PPT
Project quality management in manufacturing
PDF
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
OOP with Java - Java Introduction (Basics)
additive manufacturing of ss316l using mig welding
MET 305 2019 SCHEME MODULE 2 COMPLETE.pptx
Digital Logic Computer Design lecture notes
Infosys Presentation by1.Riyan Bagwan 2.Samadhan Naiknavare 3.Gaurav Shinde 4...
Foundation to blockchain - A guide to Blockchain Tech
Mitigating Risks through Effective Management for Enhancing Organizational Pe...
July 2025 - Top 10 Read Articles in International Journal of Software Enginee...
CH1 Production IntroductoryConcepts.pptx
UNIT 4 Total Quality Management .pptx
CYBER-CRIMES AND SECURITY A guide to understanding
Mohammad Mahdi Farshadian CV - Prospective PhD Student 2026
Construction Project Organization Group 2.pptx
SM_6th-Sem__Cse_Internet-of-Things.pdf IOT
CARTOGRAPHY AND GEOINFORMATION VISUALIZATION chapter1 NPTE (2).pptx
Recipes for Real Time Voice AI WebRTC, SLMs and Open Source Software.pptx
Internet of Things (IOT) - A guide to understanding
Arduino robotics embedded978-1-4302-3184-4.pdf
Project quality management in manufacturing
keyrequirementskkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk

Finch + Finagle OAuth2

  • 1. Finch + Finagle-OAuth2 = Purely Functional REST API Vladimir Kostyukov @vkostyukov
  • 2. Finagle-OAuth2: Highlights • Asynchronous version of Nulab’s scala-oauth2-provider ! • Finagle-friendly API: OAuth2Request, OAuth2Filter ! • Does not depend on Finch 2
  • 3. 1 trait DataHandler[U] { 2 ... 3 def findUser(username: String, password: String): Future[Option[U]] 4 def createAccessToken(authInfo: AuthInfo[U]): Future[AccessToken] 5 def getStoredAccessToken(authInfo: AuthInfo[U]): Future[Option[AccessToken]] 6 def findAccessToken(token: String): Future[Option[AccessToken]] 7 ... 8 } Finagle-OAuth2: Step #1 DataHandler 3
  • 4. Finagle-OAuth2: Step #2 Typesafe Auth 1 import com.twitter.finagle.oauth2._ 2 import com.twitter.finagle.oauth2.{OAuth2Filter, OAuth2Request} 3 4 val auth = new OAuth2Filter(dataHandler) 5 6 val hello = new Service[OAuth2Request[User], Response] { 7 def apply(req: OAuth2Request[User]) = { 8 println(s"Hello, ${req.authInfo.user}!") 9 Future.value(Response()) 10 } 11 } 12 13 val backend: Service[Request, Response] = auth andThen hello 4
  • 5. 1 import com.twitter.finagle.oauth2._ 2 import com.twitter.finagle.oauth2.OAuth2Endpoint 3 4 val tokens: Service[Request, Response] = 5 new OAuth2Endpoint(dataHandler) with OAuthErrorInJson with OAuthTokenInJson Finagle-OAuth2: Step #3 Issue Acces Token 5
  • 6. Thin layer of purely-functional basic blocks on top of Finagle for building composable REST APIs Finch https://github.com/finagle/finch 6
  • 7. Finch: Highlights • Was #1 Scala trending repo on GitHub for 95 mins ! ! ! ! ! ! ! • Happily used in production by 2 customers: • Konfettin • JusBrasil ! • Super simple & lightweight (~ 1.5k SLOC) 7
  • 8. Finch: 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 => 11 BasicallyAuthorize("user", "password") ! hello(name) 12 } 13 } 14 15 val service: Service[HttpRequest, HttpResponse] = endpoint.toService 8
  • 9. Finch: Request Reader (Reader Monad) 1 trait RequestReader[A] { 2 3 def apply(req: HttpRequest): Future[A] 4 5 def flatMap[B](fn: A => RequestReader[B]): RequestReader[B] = ??? 6 7 def map[B](fn: A => B): RequestReader[B] = ??? 8 } 9
  • 10. Finch: Request Reader 1 val pagination: RequestReader[(Int, Int)] = for { 2 offset <- OptionalIntParam("offset") 3 limit <- OptionalIntParam("limit") 4 } yield (offset.getOrElse(0), math.min(limit.getOrElse(50), 50)) 5 6 val service = new Service[HttpRequest, HttpResponse] { 7 def apply(req: HttpRequest) = for { 8 (offsetIt, limit) <- pagination(req) 9 } yield Ok(s"Fetching items $offset..${offset+limit}") 10 } 10
  • 11. Finch: Params Validation 1 case class User(age: Int) 2 3 val user: RequestReader[User] = 4 for { age <- RequiredIntParam("age") } yield User(age) 5 6 val adult: RequestReader[User] = for { 7 u <- user 8 _ <- ValidationRule("age", "should be greater then 18") { user.age > 18 } 9 } yield u 10 11 val u: Future[JsonResponse] = adult(request) map { 12 JsonObject("age" -> _.age) 13 } handle { 14 case e: ParamNotFound => 15 JsonObject("error" -> e.getMessage, "param" -> e.param) 16 case e: ValidationFailed => 17 JsonObject("error" -> e.getMessage, "param" -> e.param) 18 } 11
  • 12. Finch: Request Reader Highlights • RequiredParam, RequiredIntParam, etc • Future.value[A] • Future.exception[ParamNotFound] ! • OptionalParam, OptionalIntParam, etc • Future.value[Option[A]] ! • Multi-value Params: RequiredParams, OptionalIntParams, etc. • Future.value[List[A]] ! • Params Validation: ValidationRule • Future.value[Unit] • Future.exception[ValidationFailed] 12
  • 13. Finch: Responses 1 // 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" -> 100)) 9 10 // ‘plain/text' response with custom header and status 403 11 val d = Forbidden.withHeaders("Some-Header" -> "Secret")("body") 13
  • 14. Finch: Endpoints Highlights • Finch’s Endpoints are composable routers ! • Endpoints might be treated as Scala’s PartialFunctions[Request, Service[_, _]] ! • Endpoints are convertible to Finagle Service’s ! • Endpoints might be composed with Service’s, Filter’s or other Endpoint’s. 14
  • 15. Finch: Endpoints Composition 1 val ab: Filter[A, C, B, C] = ??? 2 val bc: Endpoint[B, C] = ??? 3 val cd: Service[C, D] 4 5 val ad1: Endpoint[A, D] = ab ! bc ! cd 6 val ad2: Endpoint[A, D] = ??? 7 8 val ad3: Endpoint[A, D] = ad1 orElse ad2 15
  • 17. • A better JSON • Lightweight in-memory caching API Finch: Further Steps 17