$30 off During Our Annual Pro Sale. View Details »

Java REST API Framework Comparison - PWX 2021

Matt Raible
December 07, 2021

Java REST API Framework Comparison - PWX 2021

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/2021/06/18/native-java-framework-comparison
GitHub repo: https://github.com/oktadev/native-java-examples

Matt Raible

December 07, 2021
Tweet

More Decks by Matt Raible

Other Decks in Programming

Transcript

  1. Matt Raible | @mraible December 7, 2021 Java REST API

    Comparison Micronaut, Quarkus, and Spring Boot Photo by Evi T. on Unsplash
  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 Download the Oracle builds of OpenJDK https://jdk.java.net/17 Or Eclipse

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

    curl -s https://get.sdkman.io | bash 
 sdk install java 17-open
  7. 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() + "!"; } }
  8. @mraible Get Started with Quarkus mvn io.quarkus:quarkus-maven-plugin:2.5.1.Final:create \ -DprojectGroupId=com.okta.rest \

    -DprojectArtifactId=quarkus \ -DclassName="com.okta.rest.quarkus.HelloResource" \ -Dpath="/hello" \ -Dextensions="smallrye-jwt,resteasy-reactive"
  9. 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() + "!"; } }
  10. @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 -
  11. 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() + "!"; } }
  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 750 1500 2250 3000 Micronaut

    Quarkus Spring Boot 1,497 568 573 1,122 1,918 456 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/smallrye-graphql Spring Boot https://spring.io/projects/spring-graphql
  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/latest/micronaut-oauth2-okta.html 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:17-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 -it -p8080: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 uses Jib, but you must

    configure plugins Quarkus generates four Docker-related files Dockerfile.jvm Dockerfile.legacy-jar Dockerfile.native Dockerfile.native-distroless 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 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 ... mvn package -Dpackaging=native-image

    gradle nativeImage gradle dockerBuildNative Go Native with GraalVM and Micronaut https://docs.micronaut.io/latest/guide/#graal
  23. @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
  24. @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
  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 Add Spring

    Native dependency <dependency> <groupId>org.springframework.experimental</groupId> <artifactId>spring-native</artifactId> <version>0.11.0-RC1</version> </dependency> Build the native application mvn spring-boot:build-image
  27. @mraible Native Startup Performance Milliseconds 0 25 50 75 100

    December 2, 2021 61.8 18.4 19.8 Micronaut Quarkus Spring Boot
  28. @mraible Native Memory Used (MB) Milliseconds 0 25 50 75

    100 December 2, 2021 58 32 78 Micronaut Quarkus Spring Boot
  29. @mraible Stack Overflow Tags 0 32500 65000 97500 130000 December

    2, 2021 61 114,122 2,171 1,242 Micronaut Quarkus Spring Boot Helidon
  30. @mraible GitHub Stars 0 18750 37500 56250 75000 December 3,

    2021 2,500 58,500 8,900 5,100 Micronaut Quarkus Spring Boot Helidon
  31. @mraible Jobs on Indeed (US) 0 3250 6500 9750 13000

    December 3, 2021 11,333 198 166 Micronaut Quarkus Spring Boot
  32. @mraible Twitter Followers 0 25000 50000 75000 100000 December 3,

    2021 3,322 80,200 13,100 10,900 Micronaut Quarkus Spring Boot Helidon
  33. @mraible JHipster Support 🤓 Micronaut Blueprint - github.com/jhipster/generator-jhipster-micronaut - v1.0.2,

    18 releases, 16 contributors, 382 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.3, Dev Services, Reactive, Microservices