Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
@codefinger#Devoxx #YourTagHere
4 JVM
Web Frameworks
in 40 minutes
@codefinger#Devoxx #YourTagHere
in 50 minutes
4 JVM
Web Frameworks
4 JVM
Web Frameworks
with 10 minutes for questions
@codefinger#Devoxx #YourTagHere
in 50 minutes
4 JVM
Web Frameworks
4 JVM
Web Frameworks
with 10 minutes for questions
±5 m...
@YourTwitterHandle#Devoxx #YourTag
Joe Kutner
@codefinger
JVM Platform Owner
@YourTwitterHandle#Devoxx #YourTag
@YourTwitterHandle#Devoxx #YourTag
Alternative
JVM languages
Scala Groovy
JRuby Clojure
What is a even a
web framework??
2015
2000 Model
View
Controller
Model
View
Controller
2015
2000
Mongo
DB
Redis
Active
MQ
AJAX
Web
Socket
CSS
Events
Async
IO
RESTSOAP
Auth
Logs
Mail
Full Stack (big circle)
MRA
A
WC
EARS
A
LM
Micro
MRA
A
WC
EARS
A
LM (little circle)
Nano
Q
(no circle)
Full Stack
Micro
Nano
Templating
Server
Docs
Stack
Tooling
Language Scala/Java
Play
Netty
A-
activator/sbt
Persistence Slick
Testing ScalaTest
F...
Full Stack Reactive Opinionated
Client Server Database
Block wait
Async IO
Client Server Database
Async wait
Async IO
Client Server PostgreSQL MongoDB
Async IO
Client Server PostgreSQL MongoDB
Client Server PostgreSQL MongoDB
Client Server PostgreSQL MongoDB
Async IO
Demo Time
Tooling
Templating
@(customer: Customer, orders: List[Order])
<h1>Welcome @customer.name!</h1>
<ul>
@for(order <- orders) {
<li>@o...
HikariCP
Database
Database Functional Relational Mapping
coffees.filter(_.price < 10.0)
val crossJoin = for {
(c, s) <- coffees join suppliers
} yield (c.name, s.name)
Database
select x2."COF_NAME", x3."SUP_NAM...
val fullOuterJoin = for {
(c, s) <- coffees joinFull suppliers on (_.supID === _.id)
} yield (c.map(_.name), s.map(_.name)...
Database Evolutions
conf/
├─ evolutions
│  └── default
│   ├── 1.sql
│   └── 2.sql
# --- !Ups
create table "people" (
"id"...
Streaming HTTP
def index = Action {
val s = getDataStream
val d: Enumerator[Array[Byte]] = Enumerator.fromStream(s)
Ok.chu...
Websockets (with Actors)
class MyWebSocketActor(out: ActorRef) extends Actor {
def receive = {
case msg: String =>
out ! (...
ScalaTest
class StackSpec extends PlaySpec {
"A Stack" must {
"pop values in last-in-first-out order" in {
val stack = new...
Pros
Great for…
• Traditional web apps with lots of IO
• Getting something up and running fast
• High Powered apps, which ...
Cons
Not so great if…
• You don’t like heavy-handed tools
• You like backward compatibility
Templating
Server
Docs
Stack
Tooling
Language Scala/Java
Play
Netty
A-
activator/sbt
Persistence Slick
Testing ScalaTest
F...
Microframework Asynchronous Unopinionated
Async IO
Client Server Database
Async wait
Demo
Templating
Time
Database
?
Testing
?
Spring Hysterix
Integrations!
Pac4j
Dropwizard
RxJava
ratpack {
bindings {
module DropwizardMetricsModule
}
handlers {
all { MetricsRegistry -> mr
mr.counter(“request-count”).i...
ratpack {
bindings {
modules HystrixModule
}
handlers {
get(“users”) {
new HysterixObservableCommand<User>(...
//...
}
}
}...
ratpack {
handlers {
get {
httpClient.get(“http://host”.toURI()) { s -> s
.headers { h ->
h.set(HttpHeaderNames.ACCEPT, “a...
Templating
Server
Docs
Stack
Tooling
Language Scala/Java
Play
Netty
A-
activator/sbt
Persistence Slick
Testing ScalaTest
F...
vs.
Strengths
Netty Netty
Full-Stack Microservices
Traditional Web-app API, Circuit Breaker
Weaknesses
Monolith New(ish)
A...
Demo
@codefinger#Devoxx #LameSlideTemplate
@codefinger#Devoxx #YourTagHere
in 50 minutes
4 JVM
Web Frameworks
4 JVM
Web Frameworks
with 10 minutes for questions
±5 m...
why java?
Full Stack Convention Opinionated
Full Stack
Synchronous IO
Client Server Database
Block wait
Demo Time
Tooling
$ rails new
$ rails generate
$ rails asset:precompile
$ rails server
$ rake routes
Templating ERB
<% @books.each do |book| %>
<tr>
<td><%= book.title %></td>
<td><%= book.content %></td>
<td><%= link_to "S...
Database ActiveRecord
class Person < ActiveRecord::Base
end
class CreatePerson < ActiveRecord::Migration
def change
create...
Torquebox
Torquebox
Templating
Server
Docs
Stack
Tooling
Language Scala/Java
Play
Netty
A-
activator/sbt
Persistence Slick
Testing ScalaTest
F...
vs.
Strengths
Netty Torquebox
Full-Stack Full-Stack
Traditional Web App Traditional Web App
Weaknesses
Complex (Scala) Opi...
Nano Modular (Un)opinionated
Libraries
F****work is a dirty word
For
developers…
Demo Time
REPL Driven Development
Templating
Hiccup Selmer
(html [:ul
(for [x (range 1 4)]
[:li x])])
<ul>
{% for item in items %}
<li> {{item}} </li>
{% en...
ClojureScript
var zero = 0;
if (zero) {
console.log("Nope!");
} else {
console.log("Zero is false!");
}
(def zero 0)
(if z...
Database
(with-transaction [t-conn conn]
(create-user!
{:id "foo"
:first_name "Sam"
:last_name "Smith"})
(get-user {:id "f...
Server
Immutant
caching
messaging
scheduling
transactions
logging
websockets
Websockets
(defn reverser
"An example WebSocket app"
[request]
(async/as-channel request
{:on-open (fn [channel]
(async/se...
Templating
Server
Docs
Stack
Tooling
Language Scala/Java
Play
Netty
A-
activator/sbt
Persistence Slick
Testing ScalaTest
F...
vs.
Strengths
Netty Immutant
Microservices Client-Side Web App
API, Circuit Breaker Traditional Web App
Weaknesses
Async I...
There is one thing
all of these frameworks
have in common
NO WAR FILES
modern JVM
web development
uses alternative
languages
pick one
Scala Groovy
JRuby Clojure
$ lazybones create ratpack my-app
$ activator new my-app
$ rails new my-app
$ lein new luminous my-app
@codefinger#Devoxx #YourTagHere
Joe Kutner
@codefinger
JVM Platform Owner
thank you!
4 JVM Web Frameworks
4 JVM Web Frameworks
4 JVM Web Frameworks
Upcoming SlideShare
Loading in …5
×

4 JVM Web Frameworks

Devoxx 2015 talk

  • Be the first to comment

4 JVM Web Frameworks

  1. 1. @codefinger#Devoxx #YourTagHere 4 JVM Web Frameworks in 40 minutes
  2. 2. @codefinger#Devoxx #YourTagHere in 50 minutes 4 JVM Web Frameworks 4 JVM Web Frameworks with 10 minutes for questions
  3. 3. @codefinger#Devoxx #YourTagHere in 50 minutes 4 JVM Web Frameworks 4 JVM Web Frameworks with 10 minutes for questions ±5 minutes
  4. 4. @YourTwitterHandle#Devoxx #YourTag Joe Kutner @codefinger JVM Platform Owner
  5. 5. @YourTwitterHandle#Devoxx #YourTag
  6. 6. @YourTwitterHandle#Devoxx #YourTag Alternative JVM languages
  7. 7. Scala Groovy JRuby Clojure
  8. 8. What is a even a web framework??
  9. 9. 2015 2000 Model View Controller
  10. 10. Model View Controller 2015 2000 Mongo DB Redis Active MQ AJAX Web Socket CSS Events Async IO RESTSOAP Auth Logs Mail
  11. 11. Full Stack (big circle) MRA A WC EARS A LM Micro MRA A WC EARS A LM (little circle) Nano Q (no circle)
  12. 12. Full Stack Micro Nano
  13. 13. Templating Server Docs Stack Tooling Language Scala/Java Play Netty A- activator/sbt Persistence Slick Testing ScalaTest Full Groovy/Java Groovy Netty B+ Gradle — — Micro JRuby ERB Torquebox A+ Rake ActiveRecord Minitest Full Clojure Hiccup Immutant B+ Lein Yesql clojure.test Nano ?
  14. 14. Full Stack Reactive Opinionated
  15. 15. Client Server Database Block wait Async IO
  16. 16. Client Server Database Async wait Async IO
  17. 17. Client Server PostgreSQL MongoDB Async IO
  18. 18. Client Server PostgreSQL MongoDB Client Server PostgreSQL MongoDB Client Server PostgreSQL MongoDB Async IO
  19. 19. Demo Time
  20. 20. Tooling
  21. 21. Templating @(customer: Customer, orders: List[Order]) <h1>Welcome @customer.name!</h1> <ul> @for(order <- orders) { <li>@order.title</li> } </ul> val content = views.html.Hello.index(c, o)
  22. 22. HikariCP Database
  23. 23. Database Functional Relational Mapping coffees.filter(_.price < 10.0)
  24. 24. val crossJoin = for { (c, s) <- coffees join suppliers } yield (c.name, s.name) Database select x2."COF_NAME", x3."SUP_NAME" from "COFFEES" x2 inner join "SUPPLIERS" x3 compiles to… Functional Relational Mapping
  25. 25. val fullOuterJoin = for { (c, s) <- coffees joinFull suppliers on (_.supID === _.id) } yield (c.map(_.name), s.map(_.name)) Database select x2."COF_NAME", x3."SUP_NAME" from "COFFEES" x2 full outer join "SUPPLIERS" x3 on x2."SUP_ID" = x3."SUP_ID" compiles to… Functional Relational Mapping
  26. 26. Database Evolutions conf/ ├─ evolutions │  └── default │   ├── 1.sql │   └── 2.sql # --- !Ups create table "people" ( "id" serial not null primary key, "name" varchar not null, "age" int not null ); # --- !Downs drop table "people" if exists;
  27. 27. Streaming HTTP def index = Action { val s = getDataStream val d: Enumerator[Array[Byte]] = Enumerator.fromStream(s) Ok.chunked(d) }
  28. 28. Websockets (with Actors) class MyWebSocketActor(out: ActorRef) extends Actor { def receive = { case msg: String => out ! ("I received your message: " + msg) } } WebSocket.acceptWithActor[String, String] { request => out => MyWebSocketActor.props(out) }
  29. 29. ScalaTest class StackSpec extends PlaySpec { "A Stack" must { "pop values in last-in-first-out order" in { val stack = new Stack[Int] stack.push(1) stack.push(2) stack.pop() mustBe 2 stack.pop() mustBe 1 } "throw NoSuchElementException if an empty stack is popped" in { val emptyStack = new Stack[Int] a [NoSuchElementException] must be thrownBy { emptyStack.pop() } } } } Testing $ activator ~test
  30. 30. Pros Great for… • Traditional web apps with lots of IO • Getting something up and running fast • High Powered apps, which is often mutually exclusive with getting started fast.
  31. 31. Cons Not so great if… • You don’t like heavy-handed tools • You like backward compatibility
  32. 32. Templating Server Docs Stack Tooling Language Scala/Java Play Netty A- activator/sbt Persistence Slick Testing ScalaTest Full Groovy/Java Groovy Netty B+ Gradle — — Micro JRuby ERB Torquebox A+ Rake ActiveRecord Minitest Full Clojure Hiccup Immutant B+ Lein Yesql clojure.test Nano
  33. 33. Microframework Asynchronous Unopinionated
  34. 34. Async IO Client Server Database Async wait
  35. 35. Demo Templating Time
  36. 36. Database ?
  37. 37. Testing ?
  38. 38. Spring Hysterix Integrations! Pac4j Dropwizard RxJava
  39. 39. ratpack { bindings { module DropwizardMetricsModule } handlers { all { MetricsRegistry -> mr mr.counter(“request-count”).inc() next() } get { // ... } } } Metrics Dropwizard
  40. 40. ratpack { bindings { modules HystrixModule } handlers { get(“users”) { new HysterixObservableCommand<User>(... //... } } } } Fault Tolerance Hystrix Hystrix is a latency and fault tolerance library designed to isolate points of access to remote systems, services and 3rd party libraries, stop cascading failure and enable resilience in complex distributed systems where failure is inevitable.
  41. 41. ratpack { handlers { get { httpClient.get(“http://host”.toURI()) { s -> s .headers { h -> h.set(HttpHeaderNames.ACCEPT, “application/json”) } }.then { resp -> render(resp) } } } } Non-blocking HTTP Client
  42. 42. Templating Server Docs Stack Tooling Language Scala/Java Play Netty A- activator/sbt Persistence Slick Testing ScalaTest Full Groovy/Java Groovy Netty B+ Gradle — — Micro JRuby ERB Torquebox A+ Rake ActiveRecord Minitest Full Clojure Hiccup Immutant B+ Lein Yesql clojure.test Nano
  43. 43. vs. Strengths Netty Netty Full-Stack Microservices Traditional Web-app API, Circuit Breaker Weaknesses Monolith New(ish) Async IO Async IO Backward Compatibility Docs
  44. 44. Demo @codefinger#Devoxx #LameSlideTemplate
  45. 45. @codefinger#Devoxx #YourTagHere in 50 minutes 4 JVM Web Frameworks 4 JVM Web Frameworks with 10 minutes for questions ±5 minutes with a few minutes for intermission
  46. 46. why java?
  47. 47. Full Stack Convention Opinionated
  48. 48. Full Stack
  49. 49. Synchronous IO Client Server Database Block wait
  50. 50. Demo Time
  51. 51. Tooling $ rails new $ rails generate $ rails asset:precompile $ rails server $ rake routes
  52. 52. Templating ERB <% @books.each do |book| %> <tr> <td><%= book.title %></td> <td><%= book.content %></td> <td><%= link_to "Show", book %></td> <td><%= link_to "Edit", edit_book_path(book) %></td> </tr> <% end %>
  53. 53. Database ActiveRecord class Person < ActiveRecord::Base end class CreatePerson < ActiveRecord::Migration def change create_table :persons do |t| t.string :name t.references :bodyguard t.integer :age t.timestamps null: false end end end
  54. 54. Torquebox
  55. 55. Torquebox
  56. 56. Templating Server Docs Stack Tooling Language Scala/Java Play Netty A- activator/sbt Persistence Slick Testing ScalaTest Full Groovy/Java Groovy Netty B+ Gradle — — Micro JRuby ERB Torquebox A+ Rake ActiveRecord Minitest Full Clojure Hiccup Immutant B+ Lein Yesql clojure.test Nano
  57. 57. vs. Strengths Netty Torquebox Full-Stack Full-Stack Traditional Web App Traditional Web App Weaknesses Complex (Scala) Opinionated Async IO Flexible Mature Approachable (Ruby) Async IO
  58. 58. Nano Modular (Un)opinionated
  59. 59. Libraries
  60. 60. F****work is a dirty word For developers…
  61. 61. Demo Time
  62. 62. REPL Driven Development
  63. 63. Templating Hiccup Selmer (html [:ul (for [x (range 1 4)] [:li x])]) <ul> {% for item in items %} <li> {{item}} </li> {% endfor %} </ul>
  64. 64. ClojureScript var zero = 0; if (zero) { console.log("Nope!"); } else { console.log("Zero is false!"); } (def zero 0) (if zero (println "Zero is not false!")) Javascript ClojureScript
  65. 65. Database (with-transaction [t-conn conn] (create-user! {:id "foo" :first_name "Sam" :last_name "Smith"}) (get-user {:id "foo"})) Yesql --name: create-user! -- creates a new user record INSERT INTO users (id, first_name, last_name) VALUES (:id, :first_name, :last_name)
  66. 66. Server Immutant caching messaging scheduling transactions logging websockets
  67. 67. Websockets (defn reverser "An example WebSocket app" [request] (async/as-channel request {:on-open (fn [channel] (async/send! channel "Ready to reverse!")) :on-message (fn [channel m] (async/send! channel (apply str (reverse m)))) :on-close (fn [channel {:keys [code reason]}] (println "close code:" code "reason:" reason))}))
  68. 68. Templating Server Docs Stack Tooling Language Scala/Java Play Netty A- activator/sbt Persistence Slick Testing ScalaTest Full Groovy/Java Groovy Netty B+ Gradle — — Micro JRuby ERB Torquebox A+ Rake ActiveRecord Minitest Full Clojure Hiccup Immutant B+ Lein Yesql clojure.test Nano
  69. 69. vs. Strengths Netty Immutant Microservices Client-Side Web App API, Circuit Breaker Traditional Web App Weaknesses Async IO Async IO ModularModular Functional Functional
  70. 70. There is one thing all of these frameworks have in common NO WAR FILES
  71. 71. modern JVM web development uses alternative languages
  72. 72. pick one
  73. 73. Scala Groovy JRuby Clojure
  74. 74. $ lazybones create ratpack my-app $ activator new my-app $ rails new my-app $ lein new luminous my-app
  75. 75. @codefinger#Devoxx #YourTagHere Joe Kutner @codefinger JVM Platform Owner thank you!

×