Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Two Scoops of Scala
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
Kārlis Lauva
April 09, 2014
Programming
110
0
Share
Two Scoops of Scala
April tech talk at FullContact
Kārlis Lauva
April 09, 2014
More Decks by Kārlis Lauva
See All by Kārlis Lauva
Let's talk about PureScript
karlis
0
84
Going Full Monty with full.monty
karlis
1
100
The Transatlantic Struggle
karlis
0
78
Valsts pārvaldes atvērto datu semantiskās integrācijas procesi
karlis
1
200
Tornado in 1 Hour (or Less)
karlis
4
190
Other Decks in Programming
See All in Programming
GNU Makeの使い方 / How to use GNU Make
kaityo256
PRO
16
5.6k
PDI: Como Alavancar Sua Carreira e Seu Negócio
marcelgsantos
0
120
一度始めたらやめられない開発効率向上術 / Findy あなたのdotfilesを教えて!
k0kubun
4
2.9k
ルールルルルルRubyの中身の予備知識 ── RubyKaigiの前に予習しなイカ?
ydah
1
150
Claude Codeをカスタムして自分だけのClaude Codeを作ろう
terisuke
0
120
3分でわかるatama plusのQA/about atama plus QA
atamaplus
0
150
「速くなった気がする」をデータで疑う
senleaf24
0
170
Going Multiplatform with Your Android App (Android Makers 2026)
zsmb
2
390
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
170
AI時代の脳疲弊と向き合う ~言語学としてのPHP~
sakuraikotone
1
1.9k
AI時代のPhpStorm最新事情 #phpcon_odawara
yusuke
0
160
Radical Imagining - LIFT 2025-2027 Policy Agenda
lift1998
0
260
Featured
See All Featured
16th Malabo Montpellier Forum Presentation
akademiya2063
PRO
0
97
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
2
720
JAMstack: Web Apps at Ludicrous Speed - All Things Open 2022
reverentgeek
1
420
Have SEOs Ruined the Internet? - User Awareness of SEO in 2025
akashhashmi
0
310
XXLCSS - How to scale CSS and keep your sanity
sugarenia
250
1.3M
Abbi's Birthday
coloredviolet
2
6.8k
We Are The Robots
honzajavorek
0
210
Why Your Marketing Sucks and What You Can Do About It - Sophie Logan
marketingsoph
0
130
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
140
Accessibility Awareness
sabderemane
0
99
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.1k
Building Adaptive Systems
keathley
44
3k
Transcript
Two scoops of Scala & Unfiltered April 2014 FullContact techTalk
@skazhy
Scala? • object oriented and functional programming language • Type
safe • Runs on JVM
Unfiltered? • A toolkit for HTTP in Scala • Really,
really modular • Works with Netty and Jetty • Built for meetup.com realtime API • Makes good use of Scala's idioms
Toolchain • SBT - Scala Build Tool • Best conventions
from Maven world • Iterative development in SBT shell
My setup • IntelliJ + SBT console(s) inside tmux •
IntelliJ 13 has SBT support baked in
Deployment • Works great with Jenkins & Asgard • Minimal
configuration tweaks needed (wait for the next slide)
• A tool for fetching templates for Scala projects •
g8 skazhy/unfiltered-netty-rx • All SBT plugins for deployment and IntelliJ are included Bootstrapping with giter8
Using opinionated RESTful frameworks for microservices?
None
Example time!
object MyPlan extends cycle.Plan with cycle.ThreadPool with ServerErrorResponse { def
intent = { case GET(Path("/")) => ResponseString("Hello!") case OPTIONS(_) => Created ~> Location("/foo") case _ => NotFound } } unfiltered.netty.Http(1337).handler(MyPlan).run()
An Intent is a partial function that pattern matches HTTP
requests
A Plan is a binding between intent and the underlying
interface
Pattern matching • Decomposing data structures to extract certain fields
or validate them • Really powerful in Scala • “routing” mechanism in Unfiltered
None
Match on request methods • Use builtins: GET(_) POST(_) PATCH(_)
• Or define your own: object SPACEJUMP extends Method("SPACEJUMP")
What happens under the hood? class Method(method: String) { def
unapply[T](req: HttpRequest[T]) = if (req.method.equalsIgnoreCase(method)) Some(req) else None } object POST extends Method("POST")
Match on request headers BasicAuth(username, password) UserAgent("Cobook")
...on URN Path("/foobar") Path(Seg("contactLists" :: "v2" :: listId :: Nil))
// Will extract /contactLists/v2/1234
...or query parameters object AccountIdParam extends Params.Extract("numericId", Params.first ~> Params.nonempty
~> Params.long) PATCH(Params(AccountIdParam(accountId))) // Will extract 1234 from PATCH /foo?numericId=1234
None
function composition!
Responses are composable case _ => Unauthorized ~> ResponseString("No pasaran")
~> ResponseHeader("WWW-Authenticate", "Basic realm=foo")
• HTTP requests are stateless • HTTP responses are side
effects
Async made easy case req @ GET(Path("/async")) => val futureOp
= asyncOperation futureOp.onSuccess { case result => req.respond(Ok ~> ResponseString(result)) } futureOp.onFailure { case _ => req.respond(InternalServerError) }
Unfiltered plays well with RxJava too
case req @ GET(Path("/reactive")) => observableOp.subscribe( result => req.respond(ResponseString(result)) _
=> req.respond(InternalServerError) )
What about testing?
• Separate library for testing with Specs2 • Mocking with
Mockito • Comes bundled with the giter8 template unfiltered-specs2
object OperationPostSpec extends Specification { "PATCH /foo" should { lazy
val r = Http(url((host \ "foo").PATCH)) lazy val response = r() "return HTTP 200" in { response.getResponseStatus mustEqual 200 } } }
Consider using Unfiltered when you... • need an async &
lightweight HTTP service • Have separate business logic • Want to leverage the λ-force
Questions?