Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Comparing Native Java REST API Frameworks - Devoxx France 2022

Comparing Native Java REST API Frameworks - Devoxx France 2022

Use Spring Boot! No, use Micronaut!! Nooooo, Quarkus is the best!!! What about Helidon?

There are a lot of developers praising the hottest, and fastest, Java REST frameworks: Micronaut, Quarkus, Spring Boot, and Helidon. In this session, you'll learn how to do the following with each framework:

✅ Build a REST API
✅ Secure your API with OAuth 2.0
✅ Optimize for production with Docker and GraalVM

I'll also share some performance numbers and pretty graphs to compare community metrics.

Related blog post: https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison
Helidon companion post: https://developer.okta.com/blog/2022/01/06/native-java-helidon
GitHub repo: https://github.com/oktadev/native-java-examples

72a2082c6a4dd79ad68befb3db911616?s=128

Matt Raible
PRO

April 21, 2022
Tweet

More Decks by Matt Raible

Other Decks in Programming

Transcript

  1. Matt Raible | @mraible April 21, 2022 Native Java REST

    API Comparison Micronaut, Quarkus, Spring Boot, and Helidon Photo by Trish McGinity https://www.mcginityphoto.com/Portfolio/TravelandLeisure/France/i-V4VqtL5
  2. @mraible Who is Matt Raible? Father, Husband, Skier, Mountain Biker,

    Whitewater Rafter Bus Lover Web Developer and Java Champion Okta Developer Advocate Blogger on raibledesigns.com and developer.okta.com/blog @mraible
  3. None
  4. None
  5. None
  6. developer.okta.com

  7. @mraible Today’s Agenda Why Java? Build { REST, GraphQL }

    APIs with Java Secure your APIs with OAuth 2.1 Build with Docker Go Native with GraalVM https://unsplash.com/photos/JsTmUnHdVYQ
  8. @mraible Why Java? 25+ Years of use, abuse, and improvements

    Open Source code is available; many popular open source frameworks and tools Hugely Popular and widely used by many enterprises and web-scale companies
  9. @mraible Download the Oracle builds of OpenJDK https://jdk.java.net/18 Or Eclipse

    builds from Adoptium https://adoptium.net Get Started with Java 18
  10. @mraible Get Started with Java 18 Better yet, use SDKMAN!

    curl -s https://get.sdkman.io | bash 
 sdk install java 18-open
  11. Java Releases and Features

  12. https://developer.okta.com/blog/2020/01/09/java-rest-api-showdown Build REST APIs with Java

  13. https://developer.okta.com/blog/2021/06/18/native-java-framework-comparison Build Native Java REST APIs

  14. https://developer.okta.com/blog/2022/01/06/native-java-helidon Build REST APIs and Native Apps with Helidon

  15. Serverless 💵 💸 https://unsplash.com/photos/glRqyWJgUeY

  16. @mraible sdk install micronaut mn create-app com.okta.rest.app \ -b maven

    -f security-jwt -f micronaut-aot Get Started with Micronaut
  17. https://micronaut.io/launch

  18. package com.okta.rest.controller; import io.micronaut.http.MediaType; import io.micronaut.http.annotation.Controller; import io.micronaut.http.annotation.Get; import io.micronaut.http.annotation.Produces;

    import io.micronaut.security.annotation.Secured; import io.micronaut.security.rules.SecurityRule; import java.security.Principal; @Controller("/hello") public class HelloController { @Get @Secured(SecurityRule.IS_AUTHENTICATED) @Produces(MediaType.TEXT_PLAIN) public String hello(Principal principal) { return "Hello, " + principal.getName() + "!"; } }
  19. micronaut.security.enabled=true micronaut.security.token.jwt.enabled=true micronaut.security.token.jwt.signatures.jwks.okta.url= https://dev-133337.okta.com/oauth2/default/v1/keys Micronaut JWT Security

  20. micronaut.security.enabled=true micronaut.security.token.jwt.enabled=true micronaut.security.token.jwt.signatures.jwks.okta.url= https://dev-133337.okta.com/oauth2/default/v1/keys Micronaut JWT Security https://micronaut-projects.github.io/micronaut-security/latest/guide/#jwt

  21. Install HTTPie (a better cURL) $ <tool> install httpie https://httpie.org

  22. Test Micronaut with HTTPie https://httpie.org mvn mn:run http :8080/hello TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...

    http :8080/hello Authorization:"Bearer $TOKEN"
  23. Verify Micronaut API with HTTPie

  24. @mraible Get Started with Quarkus mvn io.quarkus:quarkus-maven-plugin:2.8.1.Final:create \ -DprojectGroupId=com.okta.rest \

    -DprojectArtifactId=quarkus \ -DclassName="com.okta.rest.quarkus.HelloResource" \ -Dpath="/hello" \ -Dextensions="smallrye-jwt,resteasy-reactive"
  25. https://code.quarkus.io

  26. package com.okta.rest.quarkus; import io.quarkus.security.Authenticated; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces;

    import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.SecurityContext; import java.security.Principal; @Path("/hello") public class HelloResource { @GET @Authenticated @Produces(MediaType.TEXT_PLAIN) public String hello(@Context SecurityContext context) { Principal userPrincipal = context.getUserPrincipal(); return "Hello, " + userPrincipal.getName() + "!"; } }
  27. mp.jwt.verify.publickey.location= https://dev-133337.okta.com/ oauth2/default/v1/keys mp.jwt.verify.issuer=https:// dev-133337.okta.com/oauth2/ default MicroProfile JWT Security https://www.eclipse.org/community/eclipse_newsletter/2017/september/article2.php

  28. mp.jwt.verify.publickey.location= https://dev-133337.okta.com/ oauth2/default/v1/keys mp.jwt.verify.issuer=https:// dev-133337.okta.com/oauth2/ default MicroProfile JWT Security https://www.eclipse.org/community/eclipse_newsletter/2017/september/article2.php

  29. None
  30. Test Quarkus with HTTPie https://httpie.org mvn quarkus:dev http :8080/hello TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...

    http :8080/hello Authorization:"Bearer $TOKEN"
  31. Verify Quarkus API with HTTPie

  32. @mraible Get Started with Spring Boot http https://start.spring.io/starter.zip \ dependencies==web,oauth2-resource-server,native

    \ packageName==com.okta.rest \ name==spring-boot \ type==maven-project \ baseDir==spring-boot | tar -xzvf -
  33. https://start.spring.io https://start.spring.io

  34. package com.okta.rest.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import java.security.Principal; @RestController public

    class HelloController { @GetMapping("/hello") public String hello(Principal principal) { return "Hello, " + principal.getName() + "!"; } }
  35. @mraible Optimize Tomcat for Spring Native <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <exclusions>

    <exclusion> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-core</artifactId> </exclusion> <exclusion> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-websocket</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>org.apache.tomcat.experimental</groupId> <artifactId>tomcat-embed-programmatic</artifactId> <version>${tomcat.version}</version> </dependency>
  36. Spring Security OAuth 2.0 Resource Server https://docs.spring.io/spring-security/reference/servlet/oauth2/resource-server okta.oauth2.issuer=https://dev-133337.okta.com/ oauth2/default

  37. Test Spring Boot with HTTPie https://httpie.org mvn spring-boot:run http :8080/hello

    TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN... http :8080/hello Authorization:"Bearer $TOKEN"
  38. Verify Spring Boot API with HTTPie

  39. @mraible Get Started with Helidon mvn -U archetype:generate -DinteractiveMode=false \

    -DarchetypeGroupId=io.helidon.archetypes \ -DarchetypeArtifactId=helidon-quickstart-mp \ -DarchetypeVersion=2.5.0 \ -DgroupId=com.okta.rest \ -DartifactId=helidon \ -Dpackage=com.okta.rest
  40. The Helidon CLI

  41. import io.helidon.security.Principal; import io.helidon.security.SecurityContext; import javax.ws.rs.GET; import javax.ws.rs.Path; import javax.ws.rs.Produces;

    import javax.ws.rs.core.Context; import java.util.Optional; import static javax.ws.rs.core.MediaType.TEXT_PLAIN; @Path("/hello") public class HelloResource { @GET @Produces(TEXT_PLAIN) public String hello(@Context SecurityContext context) { Optional<Principal> userPrincipal = context.userPrincipal(); return "Hello, " + userPrincipal.get().getName() + "!"; } }
  42. import com.okta.rest.controller.HelloResource; import org.eclipse.microprofile.auth.LoginConfig; import javax.enterprise.context.ApplicationScoped; import javax.ws.rs.core.Application; import java.util.Set;

    @LoginConfig(authMethod = "MP-JWT") @ApplicationScoped public class HelloApplication extends Application { @Override public Set<Class<? >> getClasses() { return Set.of(HelloResource.class); } }
  43. MicroProfile JWT Security mp.jwt.verify.issuer=https://dev-133337.okta.com/oauth2/default mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}/v1/keys https://download.eclipse.org/microprofile/microprofile-jwt-auth-1.1.1/microprofile-jwt-auth-spec.html <dependency> <groupId>io.helidon.microprofile.jwt</groupId> <artifactId>helidon-microprofile-jwt-auth</artifactId> </dependency>

  44. Test Helidon with HTTPie https://httpie.org mvn package && java -jar

    target/helidon.jar http :8080/hello TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN... http :8080/hello Authorization:"Bearer $TOKEN"
  45. Verify Helidon API with HTTPie

  46. @mraible Startup Performance Milliseconds 0 300 600 900 1200 Micronaut

    Quarkus Spring Boot Helidon 919 921 334 262 686 997 227 Dev Startup (mvn) Packaged Startup (java -jar)
  47. @mraible What about GraphQL APIs? Why GraphQL? Does your favorite

    framework support GraphQL? Micronaut https://micronaut-projects.github.io/micronaut-graphql/latest/guide Quarkus https://quarkus.io/guides/smallrye-graphql Spring Boot https://spring.io/projects/spring-graphql Helidon https://helidon.io/docs/v2/#/mp/graphql/01_mp_graphql
  48. @mraible Secure your API with OAuth 2.0 https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1

  49. @mraible Secure your API with OAuth 2.1 https://oauth.net/2.1 PKCE is

    required for all clients using the authorization code flow Redirect URIs must be compared using exact string matching The Implicit grant is omitted from this specification The Resource Owner Password Credentials grant is omitted from this specification Bearer token usage omits the use of bearer tokens in the query string of URIs Refresh tokens for public clients must either be sender-constrained or one-time use
  50. @mraible Authenticate with OpenID Connect (OIDC) What is OpenID Connect?

    Does your favorite framework support OIDC authentication? Micronaut https://guides.micronaut.io/latest/micronaut-oauth2-okta.html Quarkus https://quarkus.io/guides/security-openid-connect-web-authentication Spring Boot https://docs.spring.io/spring-security/reference/servlet/oauth2/login Helidon https://helidon.io/docs/v2/#/mp/security/02_providers#_oidc_provider
  51. What about testing?

  52. @mraible Build with Docker Create a Dockerfile 
 FROM openjdk:18-alpine

    ARG JAR_FILE=target/*.jar COPY ${JAR_FILE} app.jar EXPOSE 8080 ENTRYPOINT ["java","-jar","/app.jar"]
  53. @mraible Build with Docker Build your image docker build -t

    <tag-name> . Run your image docker run -it -p8080:8080 <tag-name>
  54. @mraible Build with Docker: Jib Get Jibby with it! mvn

    verify jib:build Or build directly to your Docker daemon mvn verify jib:dockerBuild https://github.com/GoogleContainerTools/jib
  55. @mraible Build with Docker Micronaut uses Jib, but you must

    configure plugins Quarkus generates four Docker-related files Dockerfile.jvm Dockerfile.legacy-jar Dockerfile.native Dockerfile.native-micro Quarkus + Jib mvn quarkus:add-extension -Dextensions="container-image-jib"
  56. @mraible Build with Docker Spring Boot 2.3+ has built-in support

    mvn spring-boot:build-image Uses layered JARs for faster builds dependencies snapshot-dependencies resources application https://spring.io/blog/2020/01/27/creating-docker-images-with-spring-boot-2-3-0-m1
  57. @mraible Build with Docker Helidon generates four Docker-related files Dockerfile

    Dockerfile.jlink Dockerfile.native Helidon + Jib N/A
  58. @mraible Use Micronaut CLI mn create-app ... mvn package -Dpackaging=native-image

    gradle nativeImage gradle dockerBuildNative Go Native with GraalVM and Micronaut https://docs.micronaut.io/latest/guide/#graal
  59. @mraible Go Native with GraalVM and Quarkus Create an executable

    without GraalVM installed mvn package -Pnative -Dquarkus.native.container-build=true Then, build the image docker build -f src/main/docker/Dockerfile.native -t \ <tag-name> . And run it docker run -it -p8080:8080 <tag-name> https://quarkus.io/guides/building-native-image
  60. @mraible Use start.spring.io to get plugins and profiles <plugin> <groupId>org.springframework.boot</groupId>

    <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <classifier>${repackage.classifier}</classifier> <image> <builder>paketobuildpacks/builder:tiny</builder> <env> <BP_NATIVE_IMAGE>true</BP_NATIVE_IMAGE> </env> </image> </configuration> </plugin> <plugin> <groupId>org.springframework.experimental</groupId> <artifactId>spring-aot-maven-plugin</artifactId> <version>${spring-native.version}</version> <executions> Go Native with GraalVM and Spring Boot
  61. @mraible Go Native with GraalVM and Spring Boot Add milestone

    repositories to your pom.xml <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </pluginRepository> </pluginRepositories>
  62. @mraible Go Native with GraalVM and Spring Boot Add Spring

    Native dependency <dependency> <groupId>org.springframework.experimental</groupId> <artifactId>spring-native</artifactId> <version>0.11.4</version> </dependency> Build the native application mvn spring-boot:build-image
  63. @mraible How we fixed the Okta Spring Boot Starter https://youtu.be/8vY-9tXlCW4

  64. @mraible Build the image docker build -f Dockerfile.native -t <tag-name>

    . And run it docker run --rm -p8080:8080 <tag-name> Go Native with GraalVM and Helidon
  65. @mraible Native Startup Performance Milliseconds 0 25 50 75 100

    April 19, 2022 40.4 53.8 17.6 27.8 Micronaut Quarkus Spring Boot Helidon
  66. @mraible Native Memory Used (MB) Milliseconds 0 25 50 75

    100 April 19, 2022 63 58 33 54 Micronaut Quarkus Spring Boot Helidon
  67. @mraible Tests Run on a 2019 MacBook Pro

  68. @mraible Demo Time! https://github.com/oktadev/native-java-examples

  69. Community

  70. @mraible Stack Overflow Tags 0 35000 70000 105000 140000 April

    19, 2022 65 120,613 2,549 1,323 Micronaut Quarkus Spring Boot Helidon
  71. @mraible GitHub Stars 0 18750 37500 56250 75000 April 19,

    2022 2,500 58,500 8,900 5,300 Micronaut Quarkus Spring Boot Helidon
  72. https://star-history.t9t.io/#micronaut-projects/micronaut-core&quarkusio/quarkus&spring-projects/spring-boot&oracle/helidon GitHub Star Growth

  73. @mraible Jobs on Indeed (US) 0 5500 11000 16500 22000

    April 19, 2022 5 18,516 243 157 Micronaut Quarkus Spring Boot Helidon
  74. @mraible Twitter Followers 0 25000 50000 75000 100000 April 19,

    2022 3,322 80,200 13,100 10,900 Micronaut Quarkus Spring Boot Helidon
  75. Hot Web Frameworks https://hotframeworks.com

  76. @mraible JHipster Support 🤓 Micronaut Blueprint - github.com/jhipster/generator-jhipster-micronaut - v1.0.2,

    18 releases, 17 contributors, 385 commits // TODO: Micronaut 3, Reactive, Microservices, GraalVM native images Quarkus Blueprint - github.com/jhipster/generator-jhipster-quarkus - v2.0.0-beta.1, 6 releases, 16 contributors, 550 commits // TODO: Quarkus 2.8, Dev Services, Reactive, Microservices
  77. https://developer.okta.com/blog/2021/01/20/reactive-java-microservices

  78. https://developer.okta.com/blog/2020/08/17/micronaut-jhipster-heroku

  79. https://developer.okta.com/blog/2021/03/08/jhipster-quarkus-oidc

  80. What about M1 Max? https://twitter.com/mraible/status/1509371877348843525

  81. @mraible 🏆 Quarkus provides the best DevEx, startup time, and

    memory usage 🚀 Micronaut is the easiest to use and has been since the beginning 🌱 Spring Boot has the strongest community, ecosystem, and growth 🔮 Helidon still has some catching up to do but has made great progress ⚡ Spring 6 could be a game changer My Thoughts
  82. @mraible Action! New to Java? Try Spring Boot Know Spring?

    Trial migration paths Testing is important, invest early and often Design your apps with security in mind Use OpenID Connect and OAuth 2.1 https://unsplash.com/photos/JsTmUnHdVYQ
  83. developer.okta.com/blog/tags/java @oktadev

  84. git clone https://github.com/oktadeveloper/okta-spring-webflux-react- example.git https://github.com/oktadev/native-java-examples Use the Source, Luke!

  85. Thanks! Keep in Touch raibledesigns.com @mraible Presentations speakerdeck.com/mraible Code github.com/oktadev

    developer.okta.com
  86. developer.okta.com