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
0
110
Two Scoops of Scala
April tech talk at FullContact
Kārlis Lauva
April 09, 2014
Tweet
Share
More Decks by Kārlis Lauva
See All by Kārlis Lauva
Let's talk about PureScript
karlis
0
80
Going Full Monty with full.monty
karlis
1
97
The Transatlantic Struggle
karlis
0
74
Valsts pārvaldes atvērto datu semantiskās integrācijas procesi
karlis
1
190
Tornado in 1 Hour (or Less)
karlis
4
190
Other Decks in Programming
See All in Programming
要求定義・仕様記述・設計・検証の手引き - 理論から学ぶ明確で統一された成果物定義
orgachem
PRO
1
190
[KNOTS 2026登壇資料]AIで拡張‧交差する プロダクト開発のプロセス および携わるメンバーの役割
hisatake
0
290
コントリビューターによるDenoのすゝめ / Deno Recommendations by a Contributor
petamoriken
0
210
QAフローを最適化し、品質水準を満たしながらリリースまでの期間を最短化する #RSGT2026
shibayu36
2
4.4k
izumin5210のプロポーザルのネタ探し #tskaigi_msup
izumin5210
1
140
20260127_試行錯誤の結晶を1冊に。著者が解説 先輩データサイエンティストからの指南書 / author's_commentary_ds_instructions_guide
nash_efp
1
980
Claude Codeと2つの巻き戻し戦略 / Two Rewind Strategies with Claude Code
fruitriin
0
140
余白を設計しフロントエンド開発を 加速させる
tsukuha
7
2.1k
組織で育むオブザーバビリティ
ryota_hnk
0
180
責任感のあるCloudWatchアラームを設計しよう
akihisaikeda
3
180
生成AIを活用したソフトウェア開発ライフサイクル変革の現在値
hiroyukimori
PRO
0
100
並行開発のためのコードレビュー
miyukiw
0
720
Featured
See All Featured
The browser strikes back
jonoalderson
0
390
brightonSEO & MeasureFest 2025 - Christian Goodrich - Winning strategies for Black Friday CRO & PPC
cargoodrich
3
100
SEO Brein meetup: CTRL+C is not how to scale international SEO
lindahogenes
0
2.3k
Darren the Foodie - Storyboard
khoart
PRO
2
2.4k
jQuery: Nuts, Bolts and Bling
dougneiner
65
8.4k
Exploring anti-patterns in Rails
aemeredith
2
250
The Power of CSS Pseudo Elements
geoffreycrofte
80
6.2k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
231
22k
The Psychology of Web Performance [Beyond Tellerrand 2023]
tammyeverts
49
3.3k
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
1.9k
How to Align SEO within the Product Triangle To Get Buy-In & Support - #RIMC
aleyda
1
1.4k
<Decoding/> the Language of Devs - We Love SEO 2024
nikkihalliwell
1
130
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?