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

Java REST API Comparison: Micronaut, Quarkus, a...

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.

YouTube video: https://youtu.be/JeCYjaXHMgM
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

Matt Raible

September 30, 2020
Tweet

More Decks by Matt Raible

Other Decks in Programming

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. @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. @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
  4. @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
  5. @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
  6. 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() + "!"; } }
  7. @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"
  8. 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() + "!"; } }
  9. Test Quarkus with HTTPie https://httpie.org mvn compile quarkus:dev http :8080/hello

    TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN... http :8080/hello Authorization:"Bearer $TOKEN"
  10. @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
  11. 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() + "!"; } }
  12. Test Spring Boot with HTTPie https://httpie.org mvn spring-boot:run http :8080/hello

    TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN... http :8080/hello Authorization:"Bearer $TOKEN"
  13. @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)
  14. @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
  15. @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
  16. @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
  17. @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"]
  18. @mraible Build with Docker Build your image docker build -t

    <tag-name> . Run your image docker run -i --rm -p 8080:8080 <tag-name>
  19. @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
  20. @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"
  21. @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
  22. @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
  23. @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
  24. @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); } }
  25. @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>
  26. @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/
  27. @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
  28. @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
  29. @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://...
  30. @mraible Native Startup Performance Milliseconds 0 12.5 25 37.5 50

    September 21, 2020 13 26 Micronaut Quarkus
  31. @mraible Stack Overflow Tags 0 26250 52500 78750 105000 September

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

    2020 50,600 5,900 4,100 Micronaut Quarkus Spring Boot
  33. @mraible Jobs on Indeed (US) 0 1050 2100 3150 4200

    September 20, 2020 3,745 10 12 Micronaut Quarkus Spring Boot
  34. @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