SlideShare a Scribd company logo
1 of 39
Download to read offline
Unfiltered Unveiled
The Un-framework
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Whoami
Code/train Scala/Node.js for a living
* Currently @ Gust
* Formerly @ ProQuest Flow
* Formerly @ ProQuest Udini
* Formerly @ Bol.com
* Formerly @ Xebia
* Formerly @ TomTom
* Formerly @ Sun Microsystems
© Wilfred Springer, 2015 | http://www.flotsam.nl/
What are we trying to solve here?
GET / HTTP/1.0 HTTP/1.1 200 OK
Host: nxt.flotsam.nl Date: Mon, 27 April, 2015
Accept: text/html …
Last-Modified: …
ETag: "4ce43…"
Content-Type: text/html
Content-Length: 9636
Server: AmazonS3
Content:
…
© Wilfred Springer, 2015 | http://www.flotsam.nl/
And therefore, we shall have an
∞/insane number of web
frameworks
© Wilfred Springer, 2015 | http://www.flotsam.nl/
HTTP
Stuff => Stuff
© Wilfred Springer, 2015 | http://www.flotsam.nl/
HTTP
Request => Response
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Web Application
Request1 => Response1
Request2 => Response2
Request3 => Response3
Request4 => Response4
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Wait, that rings a bell
… match {
case Request1 => Response1
case Request2 => Response2
case Request3 => Response3
case Request4 => Response4
}
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Pattern matching
def doubleOf(obj: Any) = {
obj match {
case i: Int => i * 2
case s: String => s + s
}
}
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Partial Function
{
case i: Int => i * 2
case s: String => s + s
}
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Partial Function
val doubleOf = PartialFunction[Any, Any] = {
case i: Int => i * 2
case s: String => s + s
}
doubleOf(3) // 6
doubleOf("ha") // haha
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Unfiltered Anatomy
The Intent (Simplified)
type Intent = PartialFunction[HttpRequest, ResponseFunction]
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Unfiltered Anatomy
The Intent
type Intent[A,B] = PartialFunction[
HttpRequest[A], // A: some request representation
ResponseFunction[B] // B: some response representation
]
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Unfiltered Anatomy
The Intent
{
case _ => ResponseString("yay")
}
---------------------------------
GET / => HTTP/1.1 200 OK
Content-Length: 3
Content:
yay
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Unfiltered Anatomy
Binding
import unfiltered.filter
import unfiltered.netty
// Turn it into a Jetty compatible Filter
val plan = filter.Planify(intent)
// Turn it into something Netty compatible
val plan = netty.cycle.Planify(intent)
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Unfiltered Anatomy
Launching
import unfiltered.jetty
import unfiltered.filter
import unfiltered.netty
// Turn it into a Jetty compatible Filter
val plan = filter.Planify(intent)
jetty.Server.http(8080).plan(plan).run()
// Turn it into something Netty compatible
val plan = netty.cycle.Planify(intent)
netty.Server.http(8080).plan(plan).run()
© Wilfred Springer, 2015 | http://www.flotsam.nl/
ResponseFunction
Simplified, and not really true
trait ResponseFunction[-A]
extends HttpResponse[A] => HttpResponse[A]
© Wilfred Springer, 2015 | http://www.flotsam.nl/
ResponseFunction
case … => …
case … => … ~> … ~> …
------------------------------------
Ok Html(…)
NotFound Html5(…)
ResponseString(…) JsonContent
Json(…) TextXmlContent
ResponseWriter(…) Redirect(…)
© Wilfred Springer, 2015 | http://www.flotsam.nl/
ResponseFunction
Ok ~> PlainTextContent ~> ResponseString("foo")
-----------------------------------------------------------
Ok resp.setStatus(SC_OK)
PlainTextContent resp.setContentType("text/plain")
ResponseString("foo") resp.setCharacterEncoding("UTF-8")
val writer = resp.getWriter()
writer.print("foo")
writer.close
© Wilfred Springer, 2015 | http://www.flotsam.nl/
ResponseFunction
Composition using ~>
Ok ~> PlainTextContent ~> ResponseString("foo")
NotFound ~> HtmlContent ~> Html(<html>
<body>Not found</body>
</html>)
Redirect("/index.html")
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Or rather…
Scalate
// index.scaml
!!! 5
%html
%head
%body Not found
// .scala
import unfiltered.scalate.Scalate
Ok ~> HtmlContent ~> Scalate(req, "/index.scaml")
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Matching the HttpRequest
case … => …
case … & … & … =>
GET(…) Accept(…)
POST(…) UserAgent(…)
DELETE(…) Host(…)
PUT(…) IfModifiedSince(…)
Path(…) Referer(…)
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Matching the HttpRequest
Samples
case _ =>
case GET(Path('/index'))
case GET(Path(p)) if p endsWith ".json"
case Path(Seg("give", "it", "to", "me" :: Nil))
case Path("/") & Params(params)
case Accept("application/json")
© Wilfred Springer, 2015 | http://www.flotsam.nl/
It's just extractors, dude
object DotJson {
unapply[A](req: HttpRequest[A]) = req.uri endsWith ".json"
}
case DotJson() => ResponseString("Json!")
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Summary so far
— An Intent is just a partial function
— accepting an HttpRequest,
— producing a ResponseFunction
— … which will in turn produce an HttpResponse
— Matching based on HttpRequest extractors
— Use & to compose HttpRequest extractors
— Use ~> to compose ResponseFunctions
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Upping our game
What else do we need?
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Reusable Composite ResponseFunctions
Don't Repeat Yourself
… => Ok ~> HtmlContent ~> Html(<html><body>text1</body></html>)
… => Ok ~> HtmlContent ~> Html(<html><body>text2</body></html>)
… => Ok ~> HtmlContent ~> Html(<html><body>text2</body></html>)
// vs
case class Html5(text: String)
extends ComposeResponse(
Ok ~> HtmlContent ~> Html(<html><body>{text}</body></html>)
)
… => Html5("text1")
… => Html5("text2")
… => Html5("text3")
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
or, how to use Spring AOP
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
or, how to use Spring AOP
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
How NOT to use Spring AOP
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
Kit
In general, a Kit is something that:
— Takes an Intent (but it doesn't have to)
— Produces an Intent (which it always has to)
Anything that produces an Intent should be considered
a Kit
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
Authentication
import unfiltered.kit.Auth
def verify(username: String, password: String): Boolean = …
Auth.basic(verify) { | {
case … => … | case … => …
case … => … | case … => …
case … => … | case … => …
} | }
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
// Can you tell the issue with this code?
import unfiltered.request._
import unfiltered.response._
val Simple = unfiltered.filter.Planify {
case Path("/") & Accepts.Json(_) =>
JsonContent ~> ResponseString("""{ "response": "Ok" }""")
}
unfiltered.jetty.Server(8080).plan(Simple).run()
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
Directives for error handling
import unfiltered.directives._, Directives._
val Smart = unfiltered.filter.Planify { Directive.Intent {
case Path("/") =>
for {
_ <- Accepts.Json
} yield JsonContent ~> ResponseString("""{ "response": "Ok" }""")
} }
unfiltered.jetty.Server(8080).plan(Smart).run()
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Cross Cutting Concerns
Directives for routing
val Sweet = unfiltered.filter.Planify { Directive.Intent.Path {
case "/" =>
for {
_ <- Accepts.Json
} yield JsonContent ~> ResponseString("""{ "response": "Ok" }""")
} }
unfiltered.jetty.Server(8080).plan(Sweet).run()
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Parameter Based Routing
Primitive (never do this)
case Params(ps) if ps contains "name" =>
val name = ps.get("name").head
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Parameter Based Routing
No longer preferred
// Building extractor for name parameter
object Name extends Params.Extract("name", Params.first)
case GET("/") & Name(name) =>
© Wilfred Springer, 2015 | http://www.flotsam.nl/
Parameter Based Routing
Getting it right with Directives and Interpreters
Directive.Intent {
case Path("/") =>
for {
name <- data.as.String ~> required named "name"
} yield ResponseString(name)
}
© Wilfred Springer, 2015 | http://www.flotsam.nl/
© Wilfred Springer, 2015 | http://www.flotsam.nl/

More Related Content

Similar to Unfiltered Unveiled

Real-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.ioReal-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.ioRick Copeland
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHPKing Foo
 
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7Igor Moochnick
 
Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015
Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015
Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015CODE BLUE
 
[1C1]Service Workers
[1C1]Service Workers[1C1]Service Workers
[1C1]Service WorkersNAVER D2
 
Webcast: Asynchronous Programming Demystified
Webcast: Asynchronous Programming DemystifiedWebcast: Asynchronous Programming Demystified
Webcast: Asynchronous Programming DemystifiedSerge Baranovsky
 
Angular 4 The new Http Client Module
Angular 4 The new Http Client ModuleAngular 4 The new Http Client Module
Angular 4 The new Http Client Modulearjun singh
 
Ajax to the Moon
Ajax to the MoonAjax to the Moon
Ajax to the Moondavejohnson
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server renderingZiad Saab
 
Servlet 3.1 Async I/O
Servlet 3.1 Async I/OServlet 3.1 Async I/O
Servlet 3.1 Async I/OSimone Bordet
 
Phpconf 2013 - Agile Telephony Applications with PAMI and PAGI
Phpconf 2013 - Agile Telephony Applications with PAMI and PAGIPhpconf 2013 - Agile Telephony Applications with PAMI and PAGI
Phpconf 2013 - Agile Telephony Applications with PAMI and PAGIMarcelo Gornstein
 
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)danwrong
 
Tornado web
Tornado webTornado web
Tornado webkurtiss
 
Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenchesJordi Gerona
 

Similar to Unfiltered Unveiled (20)

- Webexpo 2010
- Webexpo 2010- Webexpo 2010
- Webexpo 2010
 
Real-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.ioReal-Time Python Web: Gevent and Socket.io
Real-Time Python Web: Gevent and Socket.io
 
Implementing Comet using PHP
Implementing Comet using PHPImplementing Comet using PHP
Implementing Comet using PHP
 
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
Caliburn.micro jump start composite applications for WPF, Silverlight and WP7
 
Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015
Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015
Defeating firefox by Muneaki Nishimunea - CODE BLUE 2015
 
[1C1]Service Workers
[1C1]Service Workers[1C1]Service Workers
[1C1]Service Workers
 
Expo qa 2016
Expo qa 2016Expo qa 2016
Expo qa 2016
 
Webcast: Asynchronous Programming Demystified
Webcast: Asynchronous Programming DemystifiedWebcast: Asynchronous Programming Demystified
Webcast: Asynchronous Programming Demystified
 
Angular 4 The new Http Client Module
Angular 4 The new Http Client ModuleAngular 4 The new Http Client Module
Angular 4 The new Http Client Module
 
F# on the Server-Side
F# on the Server-SideF# on the Server-Side
F# on the Server-Side
 
Python, do you even async?
Python, do you even async?Python, do you even async?
Python, do you even async?
 
Ajax to the Moon
Ajax to the MoonAjax to the Moon
Ajax to the Moon
 
WordCamp Montreal 2016 WP-API + React with server rendering
WordCamp Montreal 2016  WP-API + React with server renderingWordCamp Montreal 2016  WP-API + React with server rendering
WordCamp Montreal 2016 WP-API + React with server rendering
 
Servlet 3.1 Async I/O
Servlet 3.1 Async I/OServlet 3.1 Async I/O
Servlet 3.1 Async I/O
 
Phpconf 2013 - Agile Telephony Applications with PAMI and PAGI
Phpconf 2013 - Agile Telephony Applications with PAMI and PAGIPhpconf 2013 - Agile Telephony Applications with PAMI and PAGI
Phpconf 2013 - Agile Telephony Applications with PAMI and PAGI
 
Intro to JavaScript
Intro to JavaScriptIntro to JavaScript
Intro to JavaScript
 
Andrew Sutherland Presentation
Andrew Sutherland PresentationAndrew Sutherland Presentation
Andrew Sutherland Presentation
 
Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)Building @Anywhere (for TXJS)
Building @Anywhere (for TXJS)
 
Tornado web
Tornado webTornado web
Tornado web
 
Netty from the trenches
Netty from the trenchesNetty from the trenches
Netty from the trenches
 

More from Wilfred Springer (12)

Scala in your organisation
Scala in your organisationScala in your organisation
Scala in your organisation
 
Simplicity
SimplicitySimplicity
Simplicity
 
Unfiltered Unveiled
Unfiltered UnveiledUnfiltered Unveiled
Unfiltered Unveiled
 
Mongo
MongoMongo
Mongo
 
NoSQL
NoSQLNoSQL
NoSQL
 
NoSQL Rollercoaster
NoSQL RollercoasterNoSQL Rollercoaster
NoSQL Rollercoaster
 
Byzantine Generals
Byzantine GeneralsByzantine Generals
Byzantine Generals
 
Eventually Consistent
Eventually ConsistentEventually Consistent
Eventually Consistent
 
Into the Wild
Into the WildInto the Wild
Into the Wild
 
OOPSLA Talk on Preon
OOPSLA Talk on PreonOOPSLA Talk on Preon
OOPSLA Talk on Preon
 
Spring ME JavaOne
Spring ME JavaOneSpring ME JavaOne
Spring ME JavaOne
 
Spring ME
Spring MESpring ME
Spring ME
 

Recently uploaded

%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrainmasabamasaba
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
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
 
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
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplatePresentation.STUDIO
 
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
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...SelfMade bd
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnAmarnathKambale
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyAnusha Are
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfkalichargn70th171
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfproinshot.com
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456KiaraTiradoMicha
 
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
 
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
 
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
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfVishalKumarJha10
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfonteinmasabamasaba
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxalwaysnagaraju26
 

Recently uploaded (20)

%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
%in Bahrain+277-882-255-28 abortion pills for sale in Bahrain
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
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...
 
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 🔝✔️✔️
 
AI & Machine Learning Presentation Template
AI & Machine Learning Presentation TemplateAI & Machine Learning Presentation Template
AI & Machine Learning Presentation Template
 
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
 
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
Crypto Cloud Review - How To Earn Up To $500 Per DAY Of Bitcoin 100% On AutoP...
 
VTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learnVTU technical seminar 8Th Sem on Scikit-learn
VTU technical seminar 8Th Sem on Scikit-learn
 
Pharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodologyPharm-D Biostatistics and Research methodology
Pharm-D Biostatistics and Research methodology
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
Exploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdfExploring the Best Video Editing App.pdf
Exploring the Best Video Editing App.pdf
 
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456LEVEL 5   - SESSION 1 2023 (1).pptx - PDF 123456
LEVEL 5 - SESSION 1 2023 (1).pptx - PDF 123456
 
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
 
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
 
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-...
 
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
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdfintroduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
introduction-to-automotive Andoid os-csimmonds-ndctechtown-2021.pdf
 
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
%in kaalfontein+277-882-255-28 abortion pills for sale in kaalfontein
 
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptxBUS PASS MANGEMENT SYSTEM USING PHP.pptx
BUS PASS MANGEMENT SYSTEM USING PHP.pptx
 

Unfiltered Unveiled

  • 1. Unfiltered Unveiled The Un-framework © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 2. Whoami Code/train Scala/Node.js for a living * Currently @ Gust * Formerly @ ProQuest Flow * Formerly @ ProQuest Udini * Formerly @ Bol.com * Formerly @ Xebia * Formerly @ TomTom * Formerly @ Sun Microsystems © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 3. What are we trying to solve here? GET / HTTP/1.0 HTTP/1.1 200 OK Host: nxt.flotsam.nl Date: Mon, 27 April, 2015 Accept: text/html … Last-Modified: … ETag: "4ce43…" Content-Type: text/html Content-Length: 9636 Server: AmazonS3 Content: … © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 4. And therefore, we shall have an ∞/insane number of web frameworks © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 5. HTTP Stuff => Stuff © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 6. HTTP Request => Response © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 7. Web Application Request1 => Response1 Request2 => Response2 Request3 => Response3 Request4 => Response4 © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 8. Wait, that rings a bell … match { case Request1 => Response1 case Request2 => Response2 case Request3 => Response3 case Request4 => Response4 } © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 9. Pattern matching def doubleOf(obj: Any) = { obj match { case i: Int => i * 2 case s: String => s + s } } © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 10. Partial Function { case i: Int => i * 2 case s: String => s + s } © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 11. Partial Function val doubleOf = PartialFunction[Any, Any] = { case i: Int => i * 2 case s: String => s + s } doubleOf(3) // 6 doubleOf("ha") // haha © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 12. Unfiltered Anatomy The Intent (Simplified) type Intent = PartialFunction[HttpRequest, ResponseFunction] © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 13. Unfiltered Anatomy The Intent type Intent[A,B] = PartialFunction[ HttpRequest[A], // A: some request representation ResponseFunction[B] // B: some response representation ] © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 14. Unfiltered Anatomy The Intent { case _ => ResponseString("yay") } --------------------------------- GET / => HTTP/1.1 200 OK Content-Length: 3 Content: yay © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 15. Unfiltered Anatomy Binding import unfiltered.filter import unfiltered.netty // Turn it into a Jetty compatible Filter val plan = filter.Planify(intent) // Turn it into something Netty compatible val plan = netty.cycle.Planify(intent) © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 16. Unfiltered Anatomy Launching import unfiltered.jetty import unfiltered.filter import unfiltered.netty // Turn it into a Jetty compatible Filter val plan = filter.Planify(intent) jetty.Server.http(8080).plan(plan).run() // Turn it into something Netty compatible val plan = netty.cycle.Planify(intent) netty.Server.http(8080).plan(plan).run() © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 17. ResponseFunction Simplified, and not really true trait ResponseFunction[-A] extends HttpResponse[A] => HttpResponse[A] © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 18. ResponseFunction case … => … case … => … ~> … ~> … ------------------------------------ Ok Html(…) NotFound Html5(…) ResponseString(…) JsonContent Json(…) TextXmlContent ResponseWriter(…) Redirect(…) © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 19. ResponseFunction Ok ~> PlainTextContent ~> ResponseString("foo") ----------------------------------------------------------- Ok resp.setStatus(SC_OK) PlainTextContent resp.setContentType("text/plain") ResponseString("foo") resp.setCharacterEncoding("UTF-8") val writer = resp.getWriter() writer.print("foo") writer.close © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 20. ResponseFunction Composition using ~> Ok ~> PlainTextContent ~> ResponseString("foo") NotFound ~> HtmlContent ~> Html(<html> <body>Not found</body> </html>) Redirect("/index.html") © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 21. Or rather… Scalate // index.scaml !!! 5 %html %head %body Not found // .scala import unfiltered.scalate.Scalate Ok ~> HtmlContent ~> Scalate(req, "/index.scaml") © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 22. Matching the HttpRequest case … => … case … & … & … => GET(…) Accept(…) POST(…) UserAgent(…) DELETE(…) Host(…) PUT(…) IfModifiedSince(…) Path(…) Referer(…) © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 23. Matching the HttpRequest Samples case _ => case GET(Path('/index')) case GET(Path(p)) if p endsWith ".json" case Path(Seg("give", "it", "to", "me" :: Nil)) case Path("/") & Params(params) case Accept("application/json") © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 24. It's just extractors, dude object DotJson { unapply[A](req: HttpRequest[A]) = req.uri endsWith ".json" } case DotJson() => ResponseString("Json!") © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 25. Summary so far — An Intent is just a partial function — accepting an HttpRequest, — producing a ResponseFunction — … which will in turn produce an HttpResponse — Matching based on HttpRequest extractors — Use & to compose HttpRequest extractors — Use ~> to compose ResponseFunctions © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 26. Upping our game What else do we need? © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 27. Reusable Composite ResponseFunctions Don't Repeat Yourself … => Ok ~> HtmlContent ~> Html(<html><body>text1</body></html>) … => Ok ~> HtmlContent ~> Html(<html><body>text2</body></html>) … => Ok ~> HtmlContent ~> Html(<html><body>text2</body></html>) // vs case class Html5(text: String) extends ComposeResponse( Ok ~> HtmlContent ~> Html(<html><body>{text}</body></html>) ) … => Html5("text1") … => Html5("text2") … => Html5("text3") © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 28. Cross Cutting Concerns or, how to use Spring AOP © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 29. Cross Cutting Concerns or, how to use Spring AOP © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 30. Cross Cutting Concerns How NOT to use Spring AOP © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 31. Cross Cutting Concerns Kit In general, a Kit is something that: — Takes an Intent (but it doesn't have to) — Produces an Intent (which it always has to) Anything that produces an Intent should be considered a Kit © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 32. Cross Cutting Concerns Authentication import unfiltered.kit.Auth def verify(username: String, password: String): Boolean = … Auth.basic(verify) { | { case … => … | case … => … case … => … | case … => … case … => … | case … => … } | } © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 33. Cross Cutting Concerns // Can you tell the issue with this code? import unfiltered.request._ import unfiltered.response._ val Simple = unfiltered.filter.Planify { case Path("/") & Accepts.Json(_) => JsonContent ~> ResponseString("""{ "response": "Ok" }""") } unfiltered.jetty.Server(8080).plan(Simple).run() © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 34. Cross Cutting Concerns Directives for error handling import unfiltered.directives._, Directives._ val Smart = unfiltered.filter.Planify { Directive.Intent { case Path("/") => for { _ <- Accepts.Json } yield JsonContent ~> ResponseString("""{ "response": "Ok" }""") } } unfiltered.jetty.Server(8080).plan(Smart).run() © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 35. Cross Cutting Concerns Directives for routing val Sweet = unfiltered.filter.Planify { Directive.Intent.Path { case "/" => for { _ <- Accepts.Json } yield JsonContent ~> ResponseString("""{ "response": "Ok" }""") } } unfiltered.jetty.Server(8080).plan(Sweet).run() © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 36. Parameter Based Routing Primitive (never do this) case Params(ps) if ps contains "name" => val name = ps.get("name").head © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 37. Parameter Based Routing No longer preferred // Building extractor for name parameter object Name extends Params.Extract("name", Params.first) case GET("/") & Name(name) => © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 38. Parameter Based Routing Getting it right with Directives and Interpreters Directive.Intent { case Path("/") => for { name <- data.as.String ~> required named "name" } yield ResponseString(name) } © Wilfred Springer, 2015 | http://www.flotsam.nl/
  • 39. © Wilfred Springer, 2015 | http://www.flotsam.nl/