78
@codefinger #Devoxx #YourTagHere 4 JVM Web Frameworks in 40 minutes

4 JVM Web Frameworks

Embed Size (px)

Citation preview

Page 1: 4 JVM Web Frameworks

@codefinger#Devoxx #YourTagHere

4 JVMWeb Frameworks

in 40 minutes

Page 2: 4 JVM Web Frameworks

@codefinger#Devoxx #YourTagHere

in 50 minutes

4 JVMWeb Frameworks4 JVMWeb Frameworks

with 10 minutes for questions

Page 3: 4 JVM Web Frameworks

@codefinger#Devoxx #YourTagHere

in 50 minutes

4 JVMWeb Frameworks4 JVMWeb Frameworks

with 10 minutes for questions±5 minutes

Page 4: 4 JVM Web Frameworks

@YourTwitterHandle#Devoxx #YourTag

Joe Kutner@codefinger

JVM Platform Owner

Page 5: 4 JVM Web Frameworks

@YourTwitterHandle#Devoxx #YourTag

Page 6: 4 JVM Web Frameworks

@YourTwitterHandle#Devoxx #YourTag

Alternative JVM languages

Page 7: 4 JVM Web Frameworks

Scala Groovy

JRuby Clojure

Page 8: 4 JVM Web Frameworks

What is a even a web framework??

Page 9: 4 JVM Web Frameworks

2015

2000

Model

View

Controller

Page 10: 4 JVM Web Frameworks

Model

View

Controller

2015

2000

MongoDB Redis Active

MQ

AJAX

WebSocket

CSS

Events AsyncIORESTSOAP

Auth

Logs

Mail

Page 11: 4 JVM Web Frameworks

Full Stack (big circle)MRAAWC

EARSALM

MicroMRA

AWC

EARS

ALM (little circle)

NanoQ

(no circle)

Page 12: 4 JVM Web Frameworks

Full Stack

Micro

Nano

Page 13: 4 JVM Web Frameworks

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?

Page 14: 4 JVM Web Frameworks

Full Stack Reactive Opinionated

Page 15: 4 JVM Web Frameworks

Client Server Database

Block wait

Async IO

Page 16: 4 JVM Web Frameworks

Client Server Database

Async wait

Async IO

Page 17: 4 JVM Web Frameworks

Client Server PostgreSQL MongoDB

Async IO

Page 18: 4 JVM Web Frameworks

Client Server PostgreSQL MongoDB

Client Server PostgreSQL MongoDB

Client Server PostgreSQL MongoDB

Async IO

Page 19: 4 JVM Web Frameworks

Demo Time

Page 20: 4 JVM Web Frameworks

Tooling

Page 21: 4 JVM Web Frameworks

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)

Page 22: 4 JVM Web Frameworks

HikariCP

Database

Page 23: 4 JVM Web Frameworks

Database Functional Relational Mapping

coffees.filter(_.price < 10.0)

Page 24: 4 JVM Web Frameworks

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

Page 25: 4 JVM Web Frameworks

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

Page 26: 4 JVM Web Frameworks

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;

Page 27: 4 JVM Web Frameworks

Streaming HTTP

def index = Action { val s = getDataStream val d: Enumerator[Array[Byte]] = Enumerator.fromStream(s) Ok.chunked(d) }

Page 28: 4 JVM Web Frameworks

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) }

Page 29: 4 JVM Web Frameworks

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

Page 30: 4 JVM Web Frameworks

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.

Page 31: 4 JVM Web Frameworks

Cons

Not so great if…

• You don’t like heavy-handed tools• You like backward compatibility

Page 32: 4 JVM Web Frameworks

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

Page 33: 4 JVM Web Frameworks

Microframework Asynchronous Unopinionated

Page 34: 4 JVM Web Frameworks
Page 35: 4 JVM Web Frameworks

Async IO

Client Server Database

Async wait

Page 36: 4 JVM Web Frameworks

Demo

Templating

Time

Page 37: 4 JVM Web Frameworks

Database

?

Page 38: 4 JVM Web Frameworks

Testing

?

Page 39: 4 JVM Web Frameworks

Spring Hysterix

Integrations!

Pac4j

DropwizardRxJava

Page 40: 4 JVM Web Frameworks

ratpack { bindings { module DropwizardMetricsModule }

handlers { all { MetricsRegistry -> mr mr.counter(“request-count”).inc() next() } get { // ... } } }

Metrics Dropwizard

Page 41: 4 JVM Web Frameworks

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.

Page 42: 4 JVM Web Frameworks

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

Page 43: 4 JVM Web Frameworks

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

Page 44: 4 JVM Web Frameworks

vs.

StrengthsNetty Netty

Full-Stack Microservices

Traditional Web-app API, Circuit Breaker

Weaknesses

Monolith New(ish)

Async IO Async IO

Backward Compatibility Docs

Page 45: 4 JVM Web Frameworks

Demo

@codefinger#Devoxx #LameSlideTemplate

Page 46: 4 JVM Web Frameworks

@codefinger#Devoxx #YourTagHere

in 50 minutes

4 JVMWeb Frameworks4 JVMWeb Frameworks

with 10 minutes for questions±5 minutes

with a few minutes for intermission

Page 47: 4 JVM Web Frameworks

why java?

Page 48: 4 JVM Web Frameworks

Full Stack Convention Opinionated

Page 49: 4 JVM Web Frameworks

Full Stack

Page 50: 4 JVM Web Frameworks

Synchronous IO

Client Server Database

Block wait

Page 51: 4 JVM Web Frameworks

Demo Time

Page 52: 4 JVM Web Frameworks

Tooling

$ rails new

$ rails generate

$ rails asset:precompile

$ rails server

$ rake routes

Page 53: 4 JVM Web Frameworks

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 %>

Page 54: 4 JVM Web Frameworks

Database ActiveRecord

class Person < ActiveRecord::Baseend

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 endend

Page 55: 4 JVM Web Frameworks

Torquebox

Page 56: 4 JVM Web Frameworks

Torquebox

Page 57: 4 JVM Web Frameworks

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

Page 58: 4 JVM Web Frameworks

vs.

StrengthsNetty Torquebox

Full-Stack Full-Stack

Traditional Web App Traditional Web App

Weaknesses

Complex (Scala) Opinionated

Async IO

Flexible

Mature

Approachable (Ruby)

Async IO

Page 59: 4 JVM Web Frameworks

Nano Modular (Un)opinionated

Page 60: 4 JVM Web Frameworks

Libraries

Page 61: 4 JVM Web Frameworks

F****work is a dirty word

Fordevelopers…

Page 62: 4 JVM Web Frameworks

Demo Time

Page 63: 4 JVM Web Frameworks

REPL Driven Development

Page 64: 4 JVM Web Frameworks
Page 65: 4 JVM Web Frameworks

Templating

Hiccup Selmer

(html [:ul (for [x (range 1 4)] [:li x])])

<ul>{% for item in items %}<li> {{item}} </li>{% endfor %}</ul>

Page 66: 4 JVM Web Frameworks

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

Page 67: 4 JVM Web Frameworks

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 recordINSERT INTO users(id, first_name, last_name)VALUES (:id, :first_name, :last_name)

Page 68: 4 JVM Web Frameworks

Server

Immutant

caching

messaging

scheduling

transactions

logging

websockets

Page 69: 4 JVM Web Frameworks

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))}))

Page 70: 4 JVM Web Frameworks

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

Page 71: 4 JVM Web Frameworks

vs.

StrengthsNetty Immutant

Microservices Client-Side Web App

API, Circuit Breaker Traditional Web App

Weaknesses

Async IO

Async IO

ModularModular

Functional

Functional

Page 72: 4 JVM Web Frameworks

There is one thing all of these frameworks

have in common

NO WAR FILES

Page 73: 4 JVM Web Frameworks

modern JVM web development uses alternative languages

Page 74: 4 JVM Web Frameworks
Page 75: 4 JVM Web Frameworks

pick one

Page 76: 4 JVM Web Frameworks

Scala Groovy

JRuby Clojure

Page 77: 4 JVM Web Frameworks

$ lazybones create ratpack my-app

$ activator new my-app

$ rails new my-app

$ lein new luminous my-app

Page 78: 4 JVM Web Frameworks

@codefinger#Devoxx #YourTagHere

Joe Kutner@codefinger

JVM Platform Owner

thank you!