Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020

72a2082c6a4dd79ad68befb3db911616?s=47 Matt Raible
September 30, 2020

Java REST API Comparison: Micronaut, Quarkus, and Spring Boot - jconf.dev 2020

"Use Spring Boot! No, use Micronaut!! Nooooo, Quarkus is the best!!!"

There's a lot of developers praising the hottest, and fastest, Java REST frameworks: Micronaut, Quarkus, and Spring Boot. 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/2020/01/09/java-rest-api-showdown
GitHub repo: https://github.com/oktadeveloper/okta-java-rest-api-comparison-example

72a2082c6a4dd79ad68befb3db911616?s=128

Matt Raible

September 30, 2020
Tweet

Transcript

  1. Matt Raible | @mraible September 30, 2020 Java REST API

    Comparison Micronaut, Quarkus, and Spring Boot Photo by Matt Duncan on https://unsplash.com/photos/IUY_3DvM__w
  2. Matt Raible Developer Advocate Okta @mraible I ❤ Java AND

    JavaScript! https://jconf.dev
  3. @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
  4. None
  5. None
  6. None
  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 JDK from OpenJDK https://jdk.java.net/15 Or from AdoptOpenJDK

    https://adoptopenjdk.net Get Started with Java 15
  10. @mraible Get Started with Java 15 Better yet, use SDKMAN!

    curl -s https://get.sdkman.io | bash sdk install java 15.0.0.hs-adpt
  11. What’s New in Java 15 https://blogs.oracle.com/java-platform-group/the-arrival-of-java-15

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

  13. Serverless https://unsplash.com/photos/glRqyWJgUeY

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

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

  16. 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() + "!"; } }
  17. 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

  18. 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

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

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

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

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

    -DprojectArtifactId=quarkus \ -DclassName="com.okta.rest.quarkus.HelloResource" \ -Dpath="/hello" \ -Dextensions="jwt"
  23. https://code.quarkus.io

  24. 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 @Path("/") @Authenticated @Produces(MediaType.TEXT_PLAIN) public String hello(@Context SecurityContext context) { Principal userPrincipal = context.getUserPrincipal(); return "Hello, " + userPrincipal.getName() + "!"; } }
  25. 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

  26. 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

  27. None
  28. Test Quarkus with HTTPie https://httpie.org mvn compile quarkus:dev http :8080/hello

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

  30. @mraible Get Started with Spring Boot http https://start.spring.io/starter.zip \ dependencies==web,okta

    \ packageName==com.okta.rest \ name=spring-boot \ type=maven-project \ -o spring-boot.zip
  31. https://start.spring.io

  32. package com.okta.rest.controller; import org.springframework.security.core.annotation.AuthenticationPrincipal; 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(@AuthenticationPrincipal Principal principal) { return "Hello, " + principal.getName() + "!"; } }
  33. Spring Security OAuth 2.0 Resource Server https://docs.spring.io/spring-security/site/docs/5.4.0/reference/html5/#oauth2resourceserver okta.oauth2.issuer=https://dev-133337.okta.com/ oauth2/default

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

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

  36. @mraible Startup Performance Milliseconds 0 525 1050 1575 2100 Micronaut

    Quarkus Spring Boot 1,878 658 596 1,014 1,132 474 Dev Startup (mvn) Packaged Startup (java -jar)
  37. @mraible Build GraphQL APIs with Java Why GraphQL? Does your

    favorite framework support GraphQL? Micronaut https://micronaut-projects.github.io/micronaut-graphql/latest/guide Quarkus https://quarkus.io/guides/microprofile-graphql Spring Boot https://github.com/leangen/graphql-spqr-spring-boot-starter
  38. @mraible Secure your API with OAuth 2.0 https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1

  39. @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
  40. @mraible Authenticate with OpenID Connect (OIDC) What is OpenID Connect?

    Does your favorite framework support OIDC authentication? Micronaut https://guides.micronaut.io/micronaut-oauth2-okta/guide Quarkus https://quarkus.io/guides/security-openid-connect-web-authentication Spring Boot https://docs.spring.io/spring-security/site/docs/current/reference/html5/#oauth2login
  41. @mraible What about Testing?

  42. @mraible Build with Docker Create a Dockerfile FROM openjdk:15-alpine ARG

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

    <tag-name> . Run your image docker run -i --rm -p 8080:8080 <tag-name>
  44. @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
  45. @mraible Build with Docker Micronaut generates a Dockerfile Quarkus generates

    three Docker-related files Dockerfile.fast-jar Dockerfile.jvm Dockerfile.native Quarkus + Jib mvn quarkus:add-extension -Dextensions="container-image-jib"
  46. @mraible Build with Docker Spring Boot 2.3+ has built-in support

    mvn spring-boot:build-image Uses layered JARs for 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
  47. @mraible Use Micronaut CLI mn create-app ... -f graalvm mn

    feature-diff --features=graalvm mvn package ./docker-build.sh Go Native with GraalVM and Micronaut https://docs.micronaut.io/latest/guide/#graal
  48. @mraible Go Native with GraalVM and Quarkus It’s built-in to

    Quarkus! 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 -i --rm -p 8080:8080 <tag-name> https://quarkus.io/guides/building-native-image
  49. @mraible Go Native with GraalVM and Spring Boot Upgrade to

    Spring 2.4.0-M2 <version>2.4.0-M2</version> Update configuration to avoid proxies https://tanzu.vmware.com/content/slides/the-path-towards-spring-boot-native-applications-2 @SpringBootApplication(proxyBeanMethods = false) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }
  50. @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>
  51. @mraible Go Native with GraalVM and Spring Boot Configure your

    Spring Boot Maven Plugin <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <image> <env> <BP_BOOT_NATIVE_IMAGE>1</BP_BOOT_NATIVE_IMAGE> <BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS> -Dspring.native.remove-yaml-support=true -Dspring.spel.ignore=true --enable-https </BP_BOOT_NATIVE_IMAGE_BUILD_ARGUMENTS> </env> </image> </configuration> </plugin> https://www.graalvm.org/reference-manual/native-image/JCASecurityServices/
  52. @mraible Go Native with GraalVM and Spring Boot Add Spring

    GraalVM dependency <dependency> <groupId>org.springframework.experimental</groupId> <artifactId>spring-graalvm-native</artifactId> <version>0.8.0</version> </dependency> Build the native application mvn spring-boot:build-image
  53. @mraible Go Native with GraalVM and Spring Boot Run your

    native Spring Boot app! docker run -p 8080:8080 docker.io/library/demo:0.0.1-SNAPSHOT https://github.com/okta/okta-spring-boot/issues/192
  54. @mraible Attempted Workaround for Okta + GraalVM Use Spring Security’s

    resource server <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-security</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-resource-server</artifactId> </dependency> <dependency> <groupId>org.springframework.security</groupId> <artifactId>spring-security-oauth2-jose</artifactId> </dependency> spring.security.oauth2.resourceserver.jwt.issuer-uri=https://...
  55. @mraible Native Startup Performance Milliseconds 0 12.5 25 37.5 50

    September 21, 2020 13 26 Micronaut Quarkus
  56. @mraible Tests Run on a 2019 MacBook Pro

  57. Community

  58. @mraible Stack Overflow Tags 0 26250 52500 78750 105000 September

    20, 2020 91,030 919 732 Micronaut Quarkus Spring Boot
  59. @mraible GitHub Stars 0 15000 30000 45000 60000 September 20,

    2020 50,600 5,900 4,100 Micronaut Quarkus Spring Boot
  60. star-history.t9t.io/#micronaut-projects/micronaut-core&quarkusio/quarkus&spring-projects/spring-boot GitHub Star Growth

  61. @mraible Jobs on Indeed (US) 0 1050 2100 3150 4200

    September 20, 2020 3,745 10 12 Micronaut Quarkus Spring Boot
  62. Hot Frameworks https://hotframeworks.com

  63. @mraible JHipster Support Micronaut Blueprint - github.com/jhipster/generator-jhipster-micronaut - v0.3.8, 15

    releases, 12 contributors, 289 commits // TODO: NoSQL, Reactive, Microservices, Graal VM native images Quarkus Blueprint - github.com/jhipster/jhipster-quarkus - v0.1.6, 7 releases, 7 contributors, 80 commits // TODO: Gradle, OAuth / OIDC, NoSQL, Reactive, Microservices
  64. https://developer.okta.com/blog/2020/08/17/micronaut-jhipster-heroku

  65. @mraible Action!

  66. developer.okta.com/blog @oktadev

  67. Curious about Microservice Security? https://developer.okta.com/blog/2020/03/23/microservice-security-patterns

  68. Thanks! Keep in Touch raibledesigns.com @mraible Presentations speakerdeck.com/mraible Code github.com/oktadeveloper

    developer.okta.com
  69. developer.okta.com