SLIDE 1
Dropwizard A RESTful Love Story Ryan Kennedy (@rckenned) - - PowerPoint PPT Presentation
Dropwizard A RESTful Love Story Ryan Kennedy (@rckenned) - - PowerPoint PPT Presentation
Dropwizard A RESTful Love Story Ryan Kennedy (@rckenned) Core Services @ Yammer Dropwizard A RESTful Love Story Ryan Kennedy (@rckenned) Core
SLIDE 2
SLIDE 3
What ¡on ¡earth ¡is ¡ Dropwizard? ¡
SLIDE 4
SLIDE 5
Some ¡bearded ¡jerk ¡in ¡ ¡ a ¡pointy ¡hat… ¡
SLIDE 6
- r… ¡
SLIDE 7
SLIDE 8
Started ¡at ¡Yammer ¡as ¡three ¡services ¡ with ¡largely ¡copy/pasted ¡code ¡
SLIDE 9
By ¡service ¡number ¡three ¡we ¡ idenOfied ¡and ¡disOlled ¡the ¡paQern ¡
SLIDE 10
What ¡was ¡the ¡paQern? ¡
SLIDE 11
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 12
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 13
YAML ¡configuraOon ¡file ¡
SLIDE 14
hQp: ¡ ¡ ¡port: ¡8080 ¡ ¡ ¡adminPort: ¡8081 ¡ ¡ # ¡a ¡string ¡ foo: ¡foo ¡value ¡ ¡ # ¡a ¡duraOon ¡ bar: ¡60 ¡seconds ¡ ¡ # ¡a ¡number ¡ baz: ¡10101 ¡
SLIDE 15
ConfiguraOon ¡validaOon ¡
SLIDE 16
public ¡class ¡MyAppConfiguraOon ¡ ¡ ¡ ¡extends ¡ConfiguraOon ¡{ ¡ ¡ ¡@NotBlank ¡ ¡ ¡private ¡String ¡foo; ¡ ¡ ¡ ¡@NotNull ¡ ¡ ¡private ¡DuraOon ¡bar ¡= ¡DuraOon.minutes(10); ¡ ¡ ¡ ¡@Min(1) ¡ ¡ ¡@Max(1024) ¡ ¡ ¡private ¡long ¡baz ¡= ¡1; ¡ } ¡
SLIDE 17
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 18
SLIDE 19
Gauges ¡
Metrics.newGauge(My.class, ¡“jobs", ¡ ¡ ¡new ¡Gauge<Integer>() ¡{ ¡ ¡ ¡ ¡ ¡ ¡@Override ¡ ¡ ¡ ¡ ¡ ¡public ¡Integer ¡value() ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡queue.size(); ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡} ¡ ); ¡
SLIDE 20
Counters ¡
Counter ¡pendingJobs ¡= ¡Metrics.newCounter(My.class, ¡“jobs"); ¡ ¡ public ¡void ¡addJob(Job ¡job) ¡{ ¡ ¡ ¡ ¡ ¡pendingJobs.inc(); ¡ ¡ ¡ ¡ ¡queue.offer(job); ¡ } ¡ ¡ public ¡Job ¡takeJob() ¡{ ¡ ¡ ¡ ¡ ¡pendingJobs.dec(); ¡ ¡ ¡ ¡ ¡return ¡queue.take(); ¡ } ¡
SLIDE 21
Meters ¡
Meter ¡requests ¡= ¡Metrics.newMeter( ¡ ¡ ¡My.class, ¡"requests", ¡ ¡ ¡ ¡"requests", ¡TimeUnit.SECONDS); ¡ ¡ public ¡void ¡handleRequest(Request ¡request, ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Response ¡response) ¡{ ¡ ¡ ¡ ¡ ¡requests.mark(); ¡ ¡ ¡ ¡ ¡// ¡etc ¡ } ¡
SLIDE 22
Histograms ¡
Histogram ¡responseSizes ¡= ¡Metrics.newHistogram( ¡ ¡ ¡My.class, ¡"response-‑sizes"); ¡ ¡ public ¡void ¡handleRequest(Request ¡request, ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡Response ¡response) ¡{ ¡ ¡ ¡ ¡ ¡// ¡etc ¡ ¡ ¡ ¡ ¡int ¡length ¡= ¡response.getContent().length; ¡ ¡ ¡ ¡ ¡responseSizes.update(length); ¡ } ¡
SLIDE 23
Timers ¡
Timer ¡responses ¡= ¡Metrics.newTimer(My.class, ¡"responses", ¡ ¡ ¡ ¡TimeUnit.MILLISECONDS, ¡TimeUnit.SECONDS); ¡ ¡ public ¡String ¡handleRequest(Request ¡request, ¡Response ¡response) ¡{ ¡ ¡ ¡ ¡ ¡final ¡TimerContext ¡context ¡= ¡responses.Ome(); ¡ ¡ ¡ ¡ ¡try ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡// ¡etc; ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡"OK"; ¡ ¡ ¡ ¡ ¡} ¡finally ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡context.stop(); ¡ ¡ ¡ ¡ ¡} ¡ } ¡
SLIDE 24
Health ¡Checks ¡
public ¡class ¡DatabaseHealthCheck ¡extends ¡HealthCheck ¡{ ¡ ¡ ¡ ¡ ¡@Override ¡ ¡ ¡ ¡ ¡public ¡Result ¡check() ¡throws ¡ExcepOon ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(database.isConnected()) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡Result.healthy(); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡else ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡Result.unhealthy("Cannot ¡connect ¡to ¡db”); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡} ¡ } ¡
SLIDE 25
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 26
JMX ¡ReporOng ¡
SLIDE 27
HTTP ¡ReporOng ¡
SLIDE 28
Metrics ¡
hQp://host:adminPort/metrics ¡
SLIDE 29
SLIDE 30
SLIDE 31
Metrics ¡reporters ¡can ¡be ¡added ¡to ¡ adapt ¡dropwizard ¡metrics ¡to ¡your ¡ collecOon ¡system ¡of ¡choice ¡
SLIDE 32
Health ¡Checks ¡
hQp://host:adminPort/healthcheck ¡
SLIDE 33
SLIDE 34
Thread ¡Dumps ¡
hQp://hostname:adminPort/threads ¡
SLIDE 35
SLIDE 36
Ping ¡
hQp://hostname:adminPort/ping ¡
SLIDE 37
SLIDE 38
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 39
Dropwizard ¡provides ¡its ¡own ¡ applicaOon ¡logging ¡abstracOon ¡
SLIDE 40
HTTP ¡request ¡logging ¡is ¡ supported ¡as ¡well ¡
SLIDE 41
Dropwizard ¡provides ¡log ¡file ¡ rotaOon ¡and ¡compression ¡
SLIDE 42
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 43
The ¡unbeatable ¡Jackson ¡
SLIDE 44
“Dropwizard ¡has ¡out-‑of-‑the-‑box ¡ support ¡for ¡sophisOcated ¡ configuraOon, ¡applicaOon ¡metrics, ¡ logging, ¡operaOonal ¡tools, ¡and ¡much ¡ more, ¡allowing ¡you ¡and ¡your ¡team ¡ to ¡ship ¡a ¡producOon-‑quality ¡HTTP +JSON ¡web ¡service ¡…” ¡
SLIDE 45
Dropwizard ¡embeds ¡JeQy ¡for ¡all ¡ your ¡HTTP ¡serving ¡needs ¡
SLIDE 46
JAX-‑RS ¡(JSR-‑311) ¡for ¡all ¡your ¡ RESTful ¡needs ¡
SLIDE 47
@Path(“/users/{id}”) ¡ public ¡class ¡UserResource ¡{ ¡ ¡ ¡ ¡ ¡@GET ¡ ¡ ¡ ¡ ¡public ¡User ¡get(@PathParam(“id”) ¡long ¡id) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡db.findUserById(id); ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡ ¡@PUT ¡ ¡ ¡ ¡ ¡public ¡User ¡update(@PathParam(“id”) ¡long ¡id, ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡User ¡user) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡db.updateUser(id, ¡user); ¡ ¡ ¡ ¡ ¡} ¡ } ¡
SLIDE 48
How ¡Yammer ¡uses ¡Dropwizard ¡
SLIDE 49
Lots ¡of ¡small ¡services…16 ¡and ¡ counOng ¡
SLIDE 50
Maven ¡is ¡our ¡friend ¡
SLIDE 51
SOck ¡the ¡code ¡in ¡GitHub ¡
SLIDE 52
Shade ¡your ¡JARs ¡
SLIDE 53
Get ¡yourself ¡some ¡conOnuous ¡ integraOon ¡
SLIDE 54
Write ¡yourself ¡a ¡startup ¡script ¡
SLIDE 55
Have ¡a ¡good ¡deploy ¡story ¡
SLIDE 56
Over ¡Ome, ¡Dropwizard ¡has ¡ grown ¡a ¡few ¡appendages ¡
SLIDE 57
Dropwizard ¡Client ¡
HQpClient ¡or ¡JerseyClient ¡flavors ¡
SLIDE 58
Dropwizard ¡DB ¡
JDBI ¡as ¡a ¡service ¡
SLIDE 59
Dropwizard ¡AuthenOcaOon ¡
Abstracted ¡authenOcaOon…providers ¡ for ¡OAuth ¡2 ¡and ¡Basic ¡Auth ¡
SLIDE 60
An ¡example… ¡
@Path("/my") ¡ public ¡class ¡MyResource ¡{ ¡ ¡ ¡ ¡ ¡@GET ¡ ¡ ¡ ¡ ¡public ¡MyResponse ¡get( ¡ ¡ ¡@Auth(required ¡= ¡false) ¡Token ¡token) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡if ¡(token ¡!= ¡null) ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡new ¡MyResponse(getUser(token)); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡else ¡{ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡return ¡new ¡MyResponse(getGuestUser()); ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡ ¡} ¡ ¡ ¡ ¡ ¡} ¡ } ¡
SLIDE 61
Dropwizard ¡Views ¡
Full ¡blown ¡applicaOon ¡UIs ¡or ¡just ¡a ¡ nice ¡admin ¡interface ¡
SLIDE 62
Dropwizard ¡Scala ¡
The ¡original ¡Dropwizard…for ¡those ¡ who ¡don’t ¡know ¡any ¡beQer ¡
SLIDE 63
Dropwizard ¡TesOng ¡
Test ¡JSON ¡representaOons ¡and ¡ resources ¡
SLIDE 64
I ¡blew ¡through ¡that ¡preQy ¡ quickly, ¡fortunately ¡you ¡have… ¡
hQp://dropwizard.codahale.com/ ¡
SLIDE 65
And ¡the ¡sample ¡applicaOon ¡
hQps://github.com/codahale/ dropwizard ¡
SLIDE 66