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
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
PHP 7.4でもOpenTelemetryゼロコード計装がしたい! / PHPerKaigi 2026
arthur1
1
570
VueエンジニアがReactを触って感じた_設計の違い
koukimiura
0
170
Vibe NLP for Applied NLP
inesmontani
PRO
0
350
PHP で mp3 プレイヤーを実装しよう
m3m0r7
PRO
0
250
車輪の再発明をしよう!PHP で実装して学ぶ、Web サーバーの仕組みと HTTP の正体
h1r0
3
520
ハーネスエンジニアリングにどう向き合うか 〜ルールファイルを超えて開発プロセスを設計する〜 / How to approach harness engineering
rkaga
3
620
PHPのバージョンアップ時にも役立ったAST(2026年版)
matsuo_atsushi
0
300
Redox OS でのネームスペース管理と chroot の実現
isanethen
0
570
Go_College_最終発表資料__外部公開用_.pdf
xe_pc23
0
190
2026-03-27 #terminalnight 変数展開とコマンド展開でターミナル作業をスマートにする方法
masasuzu
0
320
Mastering Event Sourcing: Your Parents Holidayed in Yugoslavia
super_marek
0
150
SkillがSkillを生む:QA観点出しを自動化した
sontixyou
6
3.3k
Featured
See All Featured
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.1k
Data-driven link building: lessons from a $708K investment (BrightonSEO talk)
szymonslowik
1
1k
The Director’s Chair: Orchestrating AI for Truly Effective Learning
tmiket
1
150
My Coaching Mixtape
mlcsv
0
97
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
180
Helping Users Find Their Own Way: Creating Modern Search Experiences
danielanewman
31
3.1k
Crafting Experiences
bethany
1
110
Bootstrapping a Software Product
garrettdimon
PRO
307
120k
Navigating the Design Leadership Dip - Product Design Week Design Leaders+ Conference 2024
apolaine
0
270
The Power of CSS Pseudo Elements
geoffreycrofte
82
6.2k
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Max Prin - Stacking Signals: How International SEO Comes Together (And Falls Apart)
techseoconnect
PRO
0
140
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?