The ultimate smackdown

Jaap Coomans

@JaapCoomans Who is that guy?

@JaapCoomans Microframeworks Microservices framework? Microservices framework? What is a microframework? Wikipedia

“A microframework is a term used to refer to minimalistic web application frameworks. It is contrasted with full-stack frameworks.” Author: Dmitry Abramov https://pixabay.com/illustrations/elephant-pink-sitting-smile-cute-3516211/ Author: Dmitry Abramov https://pixabay.com/illustrations/panic-big-eyes-crooked-arm-1393619/ Timeline

minijax

Dropwizard

jawn light4j gemini

2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020

Redkale The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework 8. Helidon SE 24. Pippo 9. Helidon MP 25. 10. http4k 26. Proteus 11. Javalin 27. Quarkus 12. Jawn 28. Rapidoid 13. jlhttp 29. Ratpack 14. Jodd 30. Redkale 15. Jooby 31. 16. khttp 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework 10. http4k 26. Proteus 11. Javalin 27. Quarkus 12. Jawn 28. Rapidoid 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd 30. Redkale 15. Jooby 31. Scalatra 16. khttp 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework 10. http4k 26. Proteus 11. Javalin 27. Quarkus 12. Jawn 28. Rapidoid 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale 15. Jooby 31. Scalatra 16. khttp 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework 10. http4k 26. Proteus 11. Javalin 27. Quarkus 12. Jawn 28. Rapidoid 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale 15. Jooby 31. Scalatra 16. khttp | Dead project since 2017 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework | Full-stack (self-proclaimed) 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework 10. http4k 26. Proteus 11. Javalin 27. Quarkus 12. Jawn 28. Rapidoid 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale 15. Jooby 31. Scalatra 16. khttp | Dead project since 2017 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework | Full-stack (self-proclaimed) 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework | Not very micro anymore 10. http4k 26. Proteus 11. Javalin 27. Quarkus 12. Jawn 28. Rapidoid 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale 15. Jooby 31. Scalatra 16. khttp | Dead project since 2017 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework | Full-stack (self-proclaimed) 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework | Not very micro anymore 10. http4k 26. Proteus 11. Javalin 27. Quarkus | Only micro startup times… 12. Jawn 28. Rapidoid 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale 15. Jooby 31. Scalatra 16. khttp | Dead project since 2017 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework | Full-stack (self-proclaimed) 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework | Not very micro anymore 10. http4k 26. Proteus 11. Javalin 27. Quarkus | Only micro startup times… 12. Jawn 28. Rapidoid | Lack of docs for current version. 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale 15. Jooby 31. Scalatra 16. khttp | Dead project since 2017 32. Spark The long list

1. Act Framework 17. Ktor 2. Armeria 18. KumuluzEE 3. Blade 19. Light-4j 4. Dropwizard 20. Meecrowave 5. Gemini 21. Micronaut 6. GreenLightning 22. Minijax 7. Hammock 23. Ninja Framework | Full-stack (self-proclaimed) 8. Helidon SE 24. Pippo 9. Helidon MP 25. Play Framework | Not very micro anymore 10. http4k 26. Proteus 11. Javalin 27. Quarkus | Only micro startup times… 12. Jawn 28. Rapidoid | Lack of docs for current version. 13. jlhttp | GPL and custom hosting platform 29. Ratpack 14. Jodd | “Set of micro-frameworks” 30. Redkale | Docs only in Chinese 15. Jooby 31. Scalatra 16. khttp | Dead project since 2017 32. Spark Why is framework X not on your slides? Let’s sort it out

https://pixabay.com/photos/storage-sort-sorting-container-1209606/ Opinion-o-meter

Room for debate Pure OPINION facts ALERT! Licenses

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark

Dropwizard Helidon Jooby Meecrowave Proteus Licenses

Apache 2.0

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Licenses

Apache 2.0 BSD 2/3-clause

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Licenses

Apache 2.0 BSD 2/3-clause MIT

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Licenses

Apache 2.0 BSD 2/3-clause MIT LGPL 3.0

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Languages

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Languages

Java

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Languages

Java Kotlin

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Languages

Java Kotlin Groovy

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Languages

Java Kotlin Groovy Scala

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Node Go

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Model

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Model

Microprofile

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Model

Microprofile Programmatic

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Model

Microprofile Programmatic Annotations

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Model

Microprofile Programmatic Annotations JAX-RS

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Programming Model

Microprofile Programmatic Annotations JAX-RS Code generation

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Organization

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Organization

Company

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Organization

Company Non-profit org

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Organization

Company Non-profit org Community

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Web Engine

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Web Engine

Jetty

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Web Engine

Jetty Tomcat

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Web Engine

Jetty Tomcat Undertow

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Web Engine

Jetty Tomcat Undertow Netty

Act Framework Gemini http4k Ktor Micronaut Ratpack

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

Blade Hammock Jawn Light-4j Pippo Spark Java

Dropwizard Helidon Jooby Meecrowave Proteus Web Engine

Jetty Tomcat Undertow Netty Others

Act Framework Gemini http4k Ktor Micronaut Ratpack CIO Sun Apache CIO Resin (Ktor) Http

Armeria GreenLightning Javalin KumuluzEE Minijax Scalatra

???

Blade Hammock Jawn Light-4j Pippo Spark Java TJWS

Dropwizard Helidon Jooby Meecrowave Proteus To measure is to know.

Author: William Warby https://www.flickr.com/photos/wwarby/4915969081 Opinion-o-meter

Room for debate Pure OPINION facts ALERT! Google Trends Google Trends Metrics Metrics

Number of active contributors* * At least 20 commits and 1000 lines of code in the last 2 years Metrics

Number of active contributors* * At least 20 commits and 1000 lines of code in the last 2 years Stars on github Metrics

Number of active contributors* * At least 20 commits and 1000 lines of code in the last 2 years Stars on github Questions on Stack Overflow Metrics

Number of active contributors* * At least 20 commits and 1000 lines of code in the last 2 years Stars on github Questions on Stack Overflow Followers on Stack Overflow Framework Active contributors Github stars Stack Overflow Questions Stack Overflow Followers Average Index Absolute Relative Absolute Relative Absolute Relative Absolute Relative

Act Framework 1 6 629 7 12 1 7 1 4 Armeria 6 33 2400 28 4 0 6 1 16 Blade 1 6 5200 60 0 0 0 0 17 Dropwizard 3 17 7500 87 1791 100 762 100 76 Gemini 2 11 12 0 0 0 0 0 3 GreenLightning 1 6 194 2 0 0 0 0 2 Hammock 1 6 102 1 48 3 1 0 2 Helidon 7 39 1700 20 11 1 14 2 15 http4k 2 11 1300 15 8 0 6 1 7 Javalin 2 11 3700 43 17 1 9 1 14 Jawn 1 6 9 0 0 0 0 0 1 Jooby 2 11 1100 13 13 1 6 1 6 Ktor 5 28 6200 72 205 11 93 12 31 KumuluzEE 3 17 254 3 4 0 0 0 5 Light-4j 4 22 2700 31 33 2 4 1 14 Meecrowave 2 11 47 1 2 0 0 0 3 Micronaut 18 100 3400 40 482 27 189 25 48 Minijax 1 6 16 0 0 0 0 0 1 Pippo 1 6 722 8 0 0 0 0 3 Proteus 1 6 150 2 0 0 0 0 2 Ratpack 1 6 1800 21 85 5 58 8 10 Scalatra 2 11 2400 28 303 17 70 9 16 Spark Java 0 0 8600 100 496 28 139 18 36 Active contributors

20

18

15

10

7 6 5 5 4 3 3 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 0 0

Jawn Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Gemini Helidon Light-4j Minijax Proteus Ratpack Scalatra Hammock KumuluzEE Micronaut DropWizard Meecrowave Act Framework GreenLightning

Metrics retrieved at 22 January 2020 Stars on Github

10000

8600

8000 7500

6200 6000 5200

4000 3700 3400

2700 2400 2400

2000 1700 1800 1300 1100 629 722 194 254 12 102 9 47 16 150 0

Jawn Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Gemini Helidon Light-4j Minijax Proteus Ratpack Scalatra Hammock KumuluzEE Micronaut DropWizard Meecrowave Act Framework GreenLightning

Metrics retrieved at 22 January 2020 Questions on Stack Overflow (logarithmic scale)

10000

1791

1000 482 496 303 205

100 85 48 33

17 13 12 11 10 8

4 4

2

1

Jawn Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Gemini Helidon Light-4j Minijax Proteus Ratpack Scalatra Hammock KumuluzEE Micronaut DropWizard Meecrowave Act Framework GreenLightning

Metrics retrieved at 22 January 2020 Followers on Stack Overflow

800 762

600

400

200 189 139 93 58 70 14 7 6 0 0 0 1 6 9 0 6 0 4 0 0 0 0 0

Jawn Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Gemini Helidon Light-4j Minijax Proteus Ratpack Scalatra Hammock KumuluzEE Micronaut DropWizard Meecrowave Act Framework GreenLightning

Metrics retrieved at 22 January 2020 All metrics, indexed

100

75

50

25

0

Jawn Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Gemini Helidon Light-4j Minijax Proteus Ratpack Scalatra Hammock KumuluzEE Micronaut DropWizard Meecrowave Act Framework GreenLightning Active contributors Github stars SO Questions SO Followers

Metrics retrieved at 22 January 2020 All metrics, indexed, as compared to Spring Boot

5000

4500

4000

3500

3000

2500

2000

1500

1000

500

0

Jawn Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Gemini Helidon Light-4j Minijax Proteus Ratpack Scalatra Hammock KumuluzEE Micronaut Spring Boot DropWizard Meecrowave Act Framework GreenLightning Active contributors Github stars SO Questions SO Followers

Metrics retrieved at 22 January 2020 Opinion-o-meter

Room for debate Pure OPINION facts ALERT! The slightly-less-long list

1. Armeria 9. Ktor 2. Blade 10.KumuluzEE 3. Dropwizard 11.Micronaut 4. Helidon SE 12.Minijax 5. Helidon MP 13.Pippo 6. http4k 14.Ratpack 7. Javalin 15.Spark 8. Jooby https://star-history.t9t.io/ https://star-history.t9t.io/ https://star-history.t9t.io/ // TODO:

https://www.todobackend.com/ Todo Backend implementations Todo Backend implementations

6 REST endpoints Todo Backend implementations

6 REST endpoints JSON serialization (Jackson) Todo Backend implementations

6 REST endpoints JSON serialization (Jackson) CORS support Todo Backend implementations

6 REST endpoints JSON serialization (Jackson) CORS support Minimalistic setup Size of dependencies in MB (smaller is better)

25

21,4

20 17,7 16,8 17,1

15 13,8 13,4

11 9,8 10

6,4 6,3 5,9 6 4,8 4,9 5 4,3

0

Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Minijax Ratpack Helidon SE Micronaut DropWizard Helidon MP KumuluzEE Armeria Blade DropWizard Helidon MP Helidon SE http4k Javalin Jooby Ktor KumuluzEE Micronaut Minijax Pippo Ratpack Spark Number of dependencies (smaller is better)

180 162 160

140

120

99 100 89

80

60 56 45 43 40 33 30 33 26 29 29 23 22 20 16

0

Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Minijax Ratpack Helidon SE Micronaut DropWizard Helidon MP KumuluzEE Armeria Blade DropWizard Helidon MP Helidon SE http4k Javalin Jooby Ktor KumuluzEE Micronaut Minijax Pippo Ratpack Spark Startup time in ms (smaller is better)

16 GB RAM | Intel i7 4 cores | JDK 13 / 1.8

4000 3807

3500

2990 3000 2767 2676

2500

2059 1907 2000 1817 1546 1549 1500 1240 1186

1000 908 897 732

500 180

0

Ktor Blade http4k Javalin Jooby Pippo Spark Armeria Minijax Ratpack Helidon SE Micronaut DropWizard Helidon MP KumuluzEE Armeria Blade DropWizard Helidon MP Helidon SE http4k Javalin Jooby Ktor KumuluzEE Micronaut Minijax Pippo Ratpack Spark Opinion-o-meter

Room for debate Pure OPINION facts ALERT! Armeria

Async and reactive

License Apache 2.0

Organization LINE Corp. Anonymous inner classes

Language Java Programming Model Annotations Decent documentation Engines Jetty, Tomcat Github stars 2400 Object or 404 is hard Active contributors 6

Stack Overflow Questions 4

Stack Overflow followers 6 Armeria } staticpublic void LOGGER future.join CompletableFuture Server sb.annotatedService TodoRestController sb.service sb.service sb.http ServerBuilder server ( PORT .info( ( ( () "/hello/{name}" "/hello" ; ) “ = ; sb = = sb Server main sb.build , Server. future = ArmeriaApplication todoBackendApi (String[] (String[] ( todoBackendApi Started" () ; builder , ArmeriaApplication args ) ; () ) { ; server.start = ) ; createTodoBackend :: helloWorld () :: ; hello ) ; ) ; () ; Armeria } public @ProducesJson @Get } public @ConsumesJson @ProducesJson @Post return this return this return = todo Todo ( ( "/todos/{id}" HttpResponse TodoDTO .orElse(HttpResponse. .map(todo .map( command.getOrder()) "/todos" this this . .wrap(todo) todoService this .convertToJson(todo))) ) ::wrap) createTodo - . > HttpResponse.> todoService ) getTodo ; .findById(UUID. (CreateTodoCommandcommand) { ; of ( @Param .createNewTodo(command.getTitle() ( 404 of )) ; (HttpStatus. ( "id" fromString ) String) id) OK (id)) , MediaType. throws JsonProcessingException{ JSON , , Blade

Little documentation

License Apache 2.0

Most documentation in Chinese Organization Community

Language Java Not very lively Programming Model Programmatic Engine Netty Spelling errors in public API Github stars 5200 Active contributors 1

Stack Overflow Questions 0

Stack Overflow followers 0 Blade ; ) ) ; ; ) ()) hello :: args , helloWorld :: ()) class ) { ) ; args () of BladeApplication , JacksonJsonSupport corsConfiger (String[] Blade. (application) new new ( BladeApplication BladeApplication. true, , ( ( main "/hello/:name" "/hello"

jsonSupprt

enableCors .get( . .get(

application.start createTodoBackend

Blade= application JsonKit.

} public static void void publicstatic Blade , ().stream() ; ) patchTodo :: .findAll PATCH , this, ) ) " "/:id" context) { ( ; ) ) ) ()) todoService . todos "/ HttpMethod. ) deleteTodo ( this toList :: = deleteAll addRoute getTodo :: ; :: createTodo (). ) getAll :: (Blade{ application) , this, :: RouteContext ( todos , this, , this, ::wrap) > , this, todos Collectors. ( "/" "/:id" , this, this

"/" getAll "/" "/:id"

routeMatcher TodoDTO .map( .collect( .delete( . .get( .post( .delete( .get( initializeRoutes

context.json

List< application.contextPath

} private void void private

} void void Dropwizard

Built on de-facto standards

License Apache 2.0

Organization Community Targeted at microservices

Language Java Programming Model JAX-RS Many additional modules Engine Jetty Github stars 7500 Highest adoption of all Active contributors 3

Stack Overflow Questions 1790

Stack Overflow Metrics used by other frameworks followers 759 Dropwizard } class public } voidpublic @Override } staticpublic void environment.jersey var environment.jersey var this application.run var .enableCors application = application= todoRestController helloWorldController DropWizardApplication run (Configuration main ( (environment) args new new ().register( ().register( ) (String[] ; DropWizardApplication = createTodoBackend = new new configuration args ; todoRestController helloWorldController extends extends HelloWorldController ) throws Application{ , Exception { Environment environment) { () () ; ; ) ; ) ; () ; Dropwizard @Path @GET } public @Produces return return Response Response ( . .map(body .map( orElse "/{id}" this ( MediaType. this . todoService ( ) Response. ::wrap) getTodo - > Response. APPLICATION_JSON status ( .findById @ PathParam ( ok Response.Status. (body).build()) ( UUID. ( "id" fromString ) String) id) { ) NOT_FOUND (id)) ).build()) ; Helidon MP

No CORS Support

License Apache 2.0 Quite heavy to be micro Organization Oracle Language Java Less mature than expected Programming Model Microprofile Engine Netty Good documentation Github stars 1700 Active contributors 7

Stack Overflow Questions 11

Stack Overflow followers 14 Helidon MP ()) ()) ) { ) args HelloWorldApplication TodoApplication new new new ( ( (String[] main ()

;

builder addApplication addApplication . .build() .start() .

Server.

} public static void void publicstatic Helidon SE

Far more light-weight than MP

License Apache 2.0

Organization Oracle Elegant programming model

Language Java Programming Model Programmatic No native support for PATCH Engine Netty Github stars 1700 Good documentation Active contributors 7

Stack Overflow Questions 11

Stack Overflow followers 14 Helidon SE server.start var var server = = server serverConfig }) .exceptionally(t }) . ServerConfiguration. thenAccept ; return null; return t.printStackTrace System. ws.whenShutdown System. () - "WEBserver is http://localhost:" up! > WebServer. System. err out ( = ws .println .println - - > { > > { > out ( create System. ( .println ( builder " (). Startup thenRun ( serverConfig err ().port( ( "WEBserver is DOWN." failed: " " failed: ) ; (() 8080 + , ).build() t.getMessage createRouting + ws.port ; )) ()) ()) ; ()) ; ; ; Helidon SE } voidpublic @Override rules.anyOf(List. .anyOf(List. .delete( .get( .delete( .post( .get( .options( Handler. Handler. "/{id}" "/" update "/" , this, "/{id}" "/" , this , this, , this, of of (Routing.Rules rules) { ::getAll) ::corsPreflight) create create ( ( , this, PATCH GET ::deleteAll) ::getTodo) , ::deleteTodo) (PartialTodo. (CreateTodoCommand. DELETE ) , "/{id}" , POST , class,this ) , this, ::corsFilter) ::patchTodo)) class,this ::createTodo)) ; Helidon SE } private void this = id UUID . todoService . .map( ifPresentOrElse () UUID. getTodo this - > response ::wrap) fromString .findById ( ServerRequest (response::send .status (id) ( request.path ( NOT_FOUND_404 request , ().param( , ServerResponse ).send()) ID_PATH_PARAM ; response) { response) )) ; http4k

Application as a Function

License Apache 2.0 Path mapping cumbersome Organization Community Language Kotlin Request attribute, return response Programming Model Programmatic Jetty, Undertow, Netty, CIO, Engines Apache, Sun Http

Github stars 1300

Active contributors 2

Stack Overflow Questions 8

Stack Overflow followers 6 http4k , , } ) , , , deleteTodo patchTodo :: , :: getTodo deleteAll :: :: , ) createTodo "Hello World!" "Hello getAll :: :: PATCH , ( ).body( , OK ) )) todoRestController helloController DELETE todoRestController , 8080 to to Type" todoRestController to - CorsPolicy todoRestController ( to todoRestController POST to Response( GET GET todoRestController , { (Jetty( to , to PATCH DELETE GET GET ) to GET bind ( "Content ( "*" ( GET GET POST DELETE bind bind bind GET GET asServer ( listOf listOf bind bind bind listOf bind " /{id}" /{id}" /{id}" " " app. ServerFilters.Cors () ( routes

todos todos todos todos todos todos

headers = = headers methods = origins = origins "/ "/ "/ "/ "/ "/ "/hello" "/hello" "/hello/{name}" server = app =

withFilter server.start

val )))

). val http4k ) ) ) order class value . command. , title APPLICATION_JSON CreateTodoCommand:: , ().toPrettyString()) ContentType. , ) OK asJsonObject Type" .createNewTodo(command. - (). .asA(req.bodyString() wrap json "Content (req: Request): Response { Response Request): (req: todoService Response(Status. .header( .body(todo. command = todo = createTodo

return val val

} fun Javalin

Forked from Spark

License Apache 2.0

Organization Community Small, but extensible

Language Kotlin, Java Programming Model Programmatic Well documented Engine Jetty Github stars 3700 API + static files Active contributors 2

Stack Overflow Questions 17

Stack Overflow followers 9 Javalin } private static void } staticpublic void config.enableCorsForAllOrigins Javalin. .start( }) .routes(() path path create PORT ( ( "/ "/hello" ( todos JavalinApplication - > { main ) configure ; " , (String[] (String[] , helloWorldApi todoApi ( JavalinConfig args ()) () ; :: ; ) { configure ()) ; config) { config) ) Javalin EndpointGroup } void } return context.json List< } ; patch get delete post get delete getAll .collect( .map( TodoDTO ( ( ID_PATH this ( () this ( (Context context) { ( ( ID_PATH - this ID_PATH > { :: this :: getAll createTodo ( Collectors. :: todos defineEndpoints > ::wrap) deleteAll , this todos ) , this , this ; ) ; :: getTodo = :: :: toList ) patchTodo ) this deleteTodo ; ; . todoService ()) ) ; () { ; ) ; ) ; .findAll ().stream() Jooby

Supports non-blocking

License Apache 2.0 Copied JAX-RS annotations? Organization Community Language Kotlin, Java

Programmatic OR Programming Model Extensible via extensions Annotations Engines Jetty, Undertow, Netty Very well documented Github stars 1100 Active contributors 2

Stack Overflow Questions 13

Stack Overflow followers 6 Jooby ; ; )) ; ) ." PORT ( ; ms ) " startTime ; ) - ; ; + ) ) () hello setPort :: (). bootTime helloWorld ; :: ; + ()) jacksonModule jacksonModule (app) , , ServerOptions currentTimeMillis JoobyApplication json json , new new ( "Started in " "Started ( CorsHandler System. > { > JoobyApplication = - > { > , - new new .initializeRoutes (() ( MediaType. MediaType. .println ( ( app , out "/hello" "/hello/{name}" ( (

bootTime args (

long long System.

;

})

app.onStarted todoController app.get app.get app.decorator app.encoder app.decoder app.setServerOptions ;

}) runApp Jooby ; ; )) ).value()) NOT_FOUND ( ; ) class ID_PATH_PARAM ( command) , (id PartialTodo. ( StatusCodeException context.path ( (Context context) { context) (Context .updateTodo new new > - (() context.body fromString patchTodo ::wrap) todoService . this UUID. this TodoDTO orElseThrow .map( . command =

return var UUID id =

} private private Ktor

Aimed at asynchronousity

License Apache 2.0

Organization JetBrains Kotlin DSL adds learning curve

Language Kotlin Programming Model Programmatic From the makers of Kotlin Jetty, Tomcat, Engine Undertow, CIO Github stars 6200 Very rich, yet lightweight Active contributors 5

Stack Overflow Questions 205

Stack Overflow followers 93 Ktor fun fun } } install } install } routing Application. /* snip */ jackson todoRoutes } get } get call call ( ( (CORS) ( "/hello/{name}" "/hello" ContentNegotiation { . . respondText respondText {} { module () ) { ( ( () { () "Hello, "HelloWorld!" ) { ) { ${ call . parameters , ContentType.Text. [ "name" ] Plain } !" ) ) Ktor get } val val val } when ( "/{id}" else else null todo = = id .map .map .orElse( (todo) { - - > > call ) call call { { it todoService . parameters null . . . respond respond wrap ) () } (HttpStatusCode. (todo) .findById(UUID.fromString(id)) [ "id" ] NotFound ) KumuluzEE

Early Microprofile adopter

License MIT Duke’s Choice Award 2015 Organization Sunesis Language Java, Node, Go Part of a larger product suite Programming Model Microprofile Engine Jetty

Github stars 254

Active contributors 3

Stack Overflow Questions 4

Stack Overflow followers 0 KumuluzEE ; ; Application { Application ) class ; ) extends extends () { () HashSet<>() class new new getClasses ) "" ; ( KumuluzEEApplication KumuluzEEApplication classes

Set> Set>

classes.add(HelloWorldController. classes.add(TodoController. return Set> classes = = classes Set>

}

@Override public

}

publicclass @ApplicationPath KumuluzEE ; ; () { () () { () todoRepository todoService InMemoryTodoRepository() TodoService(todoRepository()) TodoBackendFactory { TodoBackendFactory TodoService TodoService TodoRepository TodoRepository

return new new return return new new return

} public @Produces } public @Produces

}

publicclass @ApplicationScoped Micronaut

Spring-inspired API

License Apache 2.0

Organization Object Computing Inc. AOT compilation

Language Java, Kotlin, Groovy Programming Model Annotations Gaining terrain fast Engine Netty

Github stars 3400

Active contributors 18 (!)

Stack Overflow Questions 482

Stack Overflow followers 189 Micronaut } class public } class public @Factory } staticpublic void } public @Bean Micronaut. return new TodoService () TodoFactory MicronautApplication { run TodoService (MicronautApplication. main todoService (String[] args) { (String[] { ( new () { InMemoryTodoRepository class ) ; ()) ; Micronaut @Patch } public return this return produces consumes consumes Optional .map( ( uri = this . todoService "/{id}" = MediaType.= = MediaType.= ::wrap) PartialTodo command) { command) PartialTodo , ; .updateTodo(UUID. patchTodo APPLICATION_JSON APPLICATION_JSON ( @PathVariable fromString , ) String id String (id) , command) , Minijax

Basically JAX-RS

License Apache 2.0 Several useful extensions available Organization Community Language Java Sparse documentation Programming Model JAX-RS Engine Undertow, Netty Basic dependency injection Github stars 16 Active contributors 1

Stack Overflow Questions 0

Simple server configuration Stack Overflow followers 0 Minijax ) class ) ) class ) class class TodoService(todoRepository)) ) new new ;

8080

Minijax() .start() .register(HelloWorldController. .register( .register(TodoController. .port( .register(JsonFeature. .register(CorsFilter. new new Pippo

Integrates with Spring, Guice, Weld

License Apache 2.0

Organization Community Extensive documentation

Language Java Programming Model Programmatic “Easy to use and hack” Jetty, Tomcat, Engine Undertow, TWJS

Github stars 722

Active contributors 1

Stack Overflow Questions 0

Stack Overflow followers 0 Pippo public staticpublic void } pippo.ANY( pippo.getServer().setPort( pippo = Pippo pippo.start() todoRestController.initializeRoutes(pippo) var pippo.GET( pippo.GET( todoRestController = "/hello/{name}" "/hello" "/.*" ; new main , createCorsHandler , Pippo() PippoApplication:: (String[] args) { (String[] createTodoBackend PORT ; , PippoApplication:: ) ; ()) ; helloWorld ; () ; hello ) ; ) ; Pippo } private void this var var . command = context.createEntityFromBody(PartialTodo. = command UUID. = id todoService .ifPresentOrElse(context.json()::send .map( .toString()) () patchTodo this - > context fromString ::wrap) ; .updateTodo(id (RouteContextcontext) { .status( (context.getParameter( 404 , )) command) ; , ID_PATH_PARAM class ) ; ) Ratpack

API / DSL targeted at Groovy

License Apache 2.0 Paths for RESTful CRUD hard Organization Community Language Groovy, Java Asynchronous, non-blocking Programming Model Programmatic Engine Netty

Github stars 1800

Active contributors 1

Stack Overflow Questions 85

Stack Overflow followers 58 Ratpack ; ) )) ) hello ; PORT :: ; ; helloWorld () (chain) ().port( ) :: Exception { Exception init ) server) { :: cors :: throws throws embedded ) RatpackApplication , args .initializeEndpoints createTodoBackend RatpackApplication = , > { - RatpackApplication (String[] (String[] ServerConfig. RatpackServerSpec ( ( ( init "hello" "hello/:name" RatpackApplication ( main start .get( .get( todoRestController chain.all ; }) .handlers(chain todoRestController

server.serverConfig var RatpackServer.

} private static void void static private

} public static void void static public Ratpack > - > - spec , () spec , () Exception { Exception ) ) ) ) ) throws throws chain.getRegistry ) ( deleteAll deleteTodo chain.getRegistry patchTodo ( :: :: createTodo :: getTodo getAll :: :: :: this this this this byMethod this this ( ( , (Chain chain) chain) (Chain byMethod , .delete( .delete( .patch( .post( /:id" " spec.get spec.get todos todos " " ) ) ; ) ) .path( .path( initializeEndpoints

chain

} void Spark

The original Java microframework

License Apache 2.0

Organization Community Unfortunately low activity

Language Java, Kotlin Programming Model Programmatic Forked by Javalin Engine Jetty Github stars 8600 Very basic Active contributors 0 (!)

Stack Overflow Questions 496

Stack Overflow Fairly well documented followers 139 Spark public staticpublic void } addCORS port setupTodoBackend get get ( ( "/hello/:name" "/hello" ( PORT () ) ; ; , SparkApplication main () , (String[] (String[] ; SparkApplication args :: helloWorld ) { :: hello ) ; ) ; Spark path var }) ; get }) path delete post jsonTransformer = ; patch delete get ( "/todos" ( "" ( ( "" "/:id" ( , ( "" "" , todoRestController ( todoRestController , ( "" , "" todoRestController todoRestController , , , , todoRestController () todoRestController () - > { > - > { > new JacksonResponseTransformer() ::getAll ::createTodo ::getTodo ::deleteAll) ::patchTodo ::deleteTodo) , jsonTransformer , jsonTransformer , ; jsonTransformer , jsonTransformer ; ) ; ) ; ; ) ; ) ; The Winners

https://pixabay.com/illustrations/cup-champion-award-trophy-winner-1613315/ The opinion-o-meter

Interpre- tations Pure OPINION facts ALERT! The winners The winners

Ktor The winners

Ktor Javalin The winners

Ktor Javalin Dropwizard The winners

Ktor Javalin Dropwizard Micronaut The winners

Ktor Javalin Dropwizard Micronaut Helidon SE Personal takeaways Personal takeaways

Maven archetypes are not dead Personal takeaways

Maven archetypes are not dead

Micro as in micro-adoption Personal takeaways

Maven archetypes are not dead

Micro as in micro-adoption

Think before you choose Thank you!

Please help me improve: @JaapCoomans In person after the session Rate my talk in the app

Get the code: https://github.com/jaapcoomans/microframeworks