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

Choosing the Right Java REST Framework - NY Java SIG 2023

Choosing the Right Java REST Framework - NY Java SIG 2023

Are you struggling to decide between the hottest and fastest Java REST frameworks? Join us at NYJavaSIG on October 19th for an insightful session where we will dive deep into the four most popular Java REST frameworks: Micronaut, Quarkus, Spring Boot, and Helidon. During this talk, we don't just preach a single framework but instead equip you with the knowledge to make an informed decision. We will cover the critical aspects of each framework, including:

✅ Building a robust and scalable REST API with ease
✅ Securing your API using the latest OAuth 2.0 security standards
✅ Leveraging Docker and GraalVM to optimize your application for production environments

But that's not all! We understand the importance of data-driven decisions. That's why we will also share real-life performance numbers and present visually appealing graphs to compare community metrics. By the end of the session, you'll have a clear understanding of how each framework stacks up against the others. Don't miss this unique opportunity to explore and compare the best Java REST frameworks with Java Champion Matt Raible!

YouTube recording: https://www.youtube.com/live/WrtKH9lGDGg?si=qWnp5_XsINDLipMo
GitHub repo: https://github.com/oktadev/auth0-java-rest-api-examples
Demo script: @oktadev/auth0-java-rest-api-examples/blob/main/demo.adoc

Matt Raible

October 19, 2023
Tweet

More Decks by Matt Raible

Other Decks in Technology

Transcript

  1. Matt Raible | @mraible
    October 19, 2023
    Choosing the Right Java REST Framework


    Micronaut, Quarkus,


    Spring Boot, and Helidon
    Photo by Florian Wehde


    https://unsplash.com/photos/high-rise-buildings-during-sunset-J6mySj3wntg

    View full-size slide

  2. @mraible
    Who is Matt Raible?
    Father, Husband, Skier, Mountain
    Biker, Whitewater Rafter


    Bus Lover


    Web Developer and Java Champion


    Developer Advocate Architect


    Blogger on raibledesigns.com and
    developer.okta.com/blog
    @mraible

    View full-size slide

  3. developer.okta.com

    View full-size slide

  4. developer.auth0.com

    View full-size slide

  5. @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

    View full-size slide

  6. @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

    View full-size slide

  7. @mraible
    Download the Oracle builds of OpenJDK


    https://jdk.java.net/21


    Or Eclipse builds from Adoptium


    https://adoptium.net
    Get Started with Java 21

    View full-size slide

  8. @mraible
    Get Started with Java 21
    Better yet, use SDKMAN!


    curl -s https://get.sdkman.io | bash

    sdk install java 21-open

    View full-size slide

  9. Java Releases and Features

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

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

    View full-size slide

  14. Use Cases for Native Images
    https://twitter.com/therealdanvega/status/1666098085616046081

    View full-size slide

  15. @mraible
    sdk install micronaut


    mn create-app com.okta.rest.app \


    -f security-jwt -f micronaut-aot
    Get Started with Micronaut

    View full-size slide

  16. https://micronaut.io/launch

    View full-size slide

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


    }


    }

    View full-size slide

  18. micronaut.security.token.jwt.signatures.jwks.okta.url=
    https://dev-1337.us.auth0.com/.well-known/jwks.json
    Micronaut JWT Security

    View full-size slide

  19. micronaut.security.token.jwt.signatures.jwks.okta.url=
    https://dev-1337.us.auth0.com/.well-known/jwks.json
    Micronaut JWT Security
    https://micronaut-projects.github.io/micronaut-security/latest/guide/#jwt

    View full-size slide

  20. Install HTTPie (a better cURL)
    $ install httpie
    https://httpie.org

    View full-size slide

  21. Test Micronaut with HTTPie
    https://httpie.org
    gradle run


    http :8080/hello


    TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...


    http :8080/hello Authorization:"Bearer $TOKEN"


    View full-size slide

  22. Verify Micronaut API with HTTPie

    View full-size slide

  23. @mraible
    Get Started with Quarkus
    sdk install quarkus


    quarkus create app com.okta.rest:quarkus \


    --extension="smallrye-jwt,resteasy-reactive"


    --gradle

    View full-size slide

  24. @mraible
    mvn io.quarkus:quarkus-maven-plugin:3.4.3:create \


    -DprojectGroupId=com.okta.rest \


    -DprojectArtifactId=quarkus \


    -DclassName="com.okta.rest.HelloResource" \


    -Dpath="/hello" \


    -Dextensions="smallrye-jwt,resteasy-reactive"
    Get Started with Quarkus

    View full-size slide

  25. https://code.quarkus.io

    View full-size slide

  26. package com.okta.rest;


    import io.quarkus.security.Authenticated;


    import jakarta.ws.rs.GET;


    import jakarta.ws.rs.Path;


    import jakarta.ws.rs.Produces;


    import jakarta.ws.rs.core.Context;


    import jakarta.ws.rs.core.MediaType;


    import jakarta.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() + "!";


    }


    }

    View full-size slide

  27. mp.jwt.verify.issuer=https://
    dev-1337.us.auth0.com/


    mp.jwt.verify.publickey.location=
    ${mp.jwt.verify.issuer}.well-
    known/jwks.json
    MicroProfile JWT Security
    https://www.eclipse.org/community/eclipse_newsletter/2017/september/article2.php

    View full-size slide

  28. mp.jwt.verify.issuer=https://
    dev-1337.us.auth0.com/


    mp.jwt.verify.publickey.location=
    ${mp.jwt.verify.issuer}.well-
    known/jwks.json
    MicroProfile JWT Security
    https://www.eclipse.org/community/eclipse_newsletter/2017/september/article2.php

    View full-size slide

  29. Test Quarkus with HTTPie
    https://httpie.org
    gradle --console=plain quarkusDev


    http :8080/hello


    TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...


    http :8080/hello Authorization:"Bearer $TOKEN"


    View full-size slide

  30. Verify Quarkus API with HTTPie

    View full-size slide

  31. @mraible
    Get Started with Spring Boot
    https start.spring.io/starter.tgz \


    dependencies==web,oauth2-resource-server,native \


    packageName==com.okta.rest \


    name==spring-boot \


    baseDir==spring-boot | tar -xzvf -

    View full-size slide

  32. https://start.spring.io
    https://start.spring.io

    View full-size slide

  33. @mraible
    Use the Spring Boot CLI
    sdk install springboot


    spring init -d=web,oauth2-resource-server,native \


    --group-id=com.okta.rest \


    --package-name=com.okta.rest spring-boot


    View full-size slide

  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() + "!";


    }


    }

    View full-size slide

  35. The Okta Spring Boot Starter
    https://github.com/okta/okta-spring-boot
    okta.oauth2.issuer=https://dev-1337.us.auth0.com

    View full-size slide

  36. Test Spring Boot with HTTPie
    https://httpie.org
    gradle bootRun


    http :8080/hello


    TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...


    http :8080/hello Authorization:"Bearer $TOKEN"


    View full-size slide

  37. Verify Spring Boot API with HTTPie

    View full-size slide

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


    -DarchetypeGroupId=io.helidon.archetypes \


    -DarchetypeArtifactId=helidon-quickstart-mp \


    -DarchetypeVersion=3.2.2 \


    -DgroupId=com.okta.rest \


    -DartifactId=helidon \


    -Dpackage=com.okta.rest

    View full-size slide

  39. https://helidon.io/starter

    View full-size slide

  40. Use the Helidon CLI
    sdk install helidon


    helidon init --flavor MP \


    --groupid com.okta.rest \


    --artifactid helidon \


    --package com.okta.rest --batch


    View full-size slide

  41. package com.okta.rest.controller;


    import io.helidon.security.Principal;


    import io.helidon.security.annotations.Authenticated;


    import jakarta.ws.rs.GET;


    import jakarta.ws.rs.Path;


    import jakarta.ws.rs.core.Context;


    @Path("/hello")


    public class HelloResource {


    @Authenticated


    @GET


    public String hello(@Context SecurityContext context) {


    return "Hello, " + context.userName() + "!";


    }


    }

    View full-size slide

  42. package com.okta.rest;


    import com.okta.rest.controller.HelloResource;


    import org.eclipse.microprofile.auth.LoginConfig;


    import jakarta.enterprise.context.ApplicationScoped;


    import jakarta.ws.rs.core.Application;


    import java.util.Set;


    @LoginConfig(authMethod = "MP-JWT")


    @ApplicationScoped


    public class HelloApplication extends Application {


    @Override


    public Set> getClasses() {


    return Set.of(HelloResource.class);


    }


    }

    View full-size slide

  43. MicroProfile JWT Security
    mp.jwt.verify.issuer=https://dev-1337.us.auth0.com/


    mp.jwt.verify.publickey.location=${mp.jwt.verify.issuer}.well-
    known/jwks.json
    https://download.eclipse.org/microprofile/microprofile-jwt-auth-2.0/microprofile-jwt-auth-spec-2.0.html



    io.helidon.microprofile.jwt


    helidon-microprofile-jwt-auth



    View full-size slide

  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"


    View full-size slide

  45. Verify Helidon API with HTTPie

    View full-size slide

  46. @mraible
    Startup Performance
    Milliseconds
    0
    500
    1000
    1500
    2000
    Micronaut Quarkus Spring Boot Helidon
    1,053
    952
    430
    433
    896
    743
    1,402
    399
    Dev Startup (gradle or mvn) Packaged Startup (java -jar)

    View full-size slide

  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/v3/#/mp/graphql

    View full-size slide

  48. @mraible
    Secure your API with OAuth 2.1
    https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1

    View full-size slide

  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

    View full-size slide

  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-auth0.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/v3/#/mp/security/providers#OIDC-Provider

    View full-size slide

  51. What about testing?

    View full-size slide

  52. @mraible
    Build with Docker
    Create a Dockerfile



    FROM openjdk:21-alpine


    ARG JAR_FILE=target/*.jar


    COPY ${JAR_FILE} app.jar


    EXPOSE 8080


    ENTRYPOINT ["java","-jar","/app.jar"]

    View full-size slide

  53. @mraible
    Build with Docker
    Build your image


    docker build -t .


    Run your image


    docker run -it -p 8080:8080

    View full-size slide

  54. @mraible
    Build with Docker: Jib
    Get Jibby with it!


    mvn verify jib:build


    gradle jib


    Or build directly to your Docker daemon


    mvn verify jib:dockerBuild


    gradle jibDockerbuild
    https://github.com/GoogleContainerTools/jib

    View full-size slide

  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"


    gradle addExtension --extensions="container-image-jib"


    View full-size slide

  56. @mraible
    Build with Docker
    Spring Boot 2.3+ has built-in support


    mvn -Pnative spring-boot:build-image

    gradle bootBuildImage

    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

    View full-size slide

  57. @mraible
    Build with Docker
    Helidon generates three Docker-related files


    Dockerfile


    Dockerfile.jlink


    Dockerfile.native


    Helidon + Jib


    Not available

    View full-size slide

  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

    View full-size slide

  59. @mraible
    Go Native with GraalVM and Quarkus
    Create an executable without GraalVM installed


    mvn package -Dnative -Dquarkus.native.container-build=true


    gradle build -Dquarkus.package.type=native \


    -Dquarkus.native.container-build=true


    Then, build the image


    docker build -f src/main/docker/Dockerfile.native -t \


    .


    And run it


    docker run -it -p 8080:8080
    https://quarkus.io/guides/building-native-image

    View full-size slide

  60. @mraible
    Use start.spring.io to get plugins


    Go Native with GraalVM and Spring Boot






    org.graalvm.buildtools


    native-maven-plugin








    org.springframework.boot


    spring-boot-maven-plugin








    plugins {


    ...


    id 'org.graalvm.buildtools.native' version '0.9.27'


    }


    View full-size slide

  61. @mraible
    Go Native with GraalVM and Spring Boot
    Build the native application


    mvn native:compile -Pnative


    gradle nativeCompile


    Build an image and Docker container


    mvn spring-boot:build-image -Pnative


    gradle bootBuildImage

    View full-size slide

  62. @mraible
    Build the image


    docker build -f Dockerfile.native -t .


    And run it


    docker run --rm -p 8080:8080
    Go Native with GraalVM and Helidon

    View full-size slide

  63. @mraible
    Native Startup Performance (M1; time from console)
    Milliseconds
    0
    12
    24
    36
    48
    60
    October 19, 2023
    35.6
    50.4
    40.4
    27.2
    17.8
    17
    Micronaut 4.1.5 Micronaut (optimized) Quarkus 3.4.3
    Spring Boot 3.1.5 Helidon 3.2.2* Helidon (optimized)

    View full-size slide

  64. @mraible
    Native Startup Performance (M1; scripted)
    Milliseconds
    0
    25
    50
    75
    100
    October 19, 2023
    53.6
    67.8
    71.6
    52.6
    49
    48.2
    Micronaut 4.1.5 Micronaut (optimized) Quarkus 3.4.3
    Spring Boot 3.1.5 Helidon 3.2.2* Helidon (optimized)

    View full-size slide

  65. @mraible
    Tests Run on a 2021 MacBook Pro M1 Max

    View full-size slide

  66. @mraible
    t2.small: 1 vCPUs and 2 GiB RAM


    - Fails to build any projects


    t2.medium: 2 vCPUs and 4 GiB RAM


    - Quarkus and Spring Boot fail to build; Helidon took too long


    t2.large: 2 vCPUs and 8 GiB RAM 🌟
    Building GraalVM images on AWS

    View full-size slide

  67. @mraible
    Native Startup Performance (AWS EC2 t2.large)
    Milliseconds
    0
    20
    40
    60
    80
    100
    October 19, 2023
    95.4
    39.8
    44
    43
    Micronaut 4.1.5 Micronaut (optimized) Quarkus 3.4.3
    Spring Boot 3.1.5

    View full-size slide

  68. @mraible
    Native Memory Used after 5 requests (M1)
    Megabytes
    0
    30
    60
    90
    120
    150
    October 19, 2023
    123
    117
    84
    53
    67
    64
    Micronaut Micronaut (optimized) Quarkus Spring Boot
    Helidon Helidon (optimized)

    View full-size slide

  69. @mraible
    Native Memory Used after 5 requests (EC2 t2.large)
    Megabytes
    0
    30
    60
    90
    120
    150
    October 19, 2023
    92
    56
    70
    71
    Micronaut Micronaut (optimized) Quarkus Spring Boot

    View full-size slide

  70. @mraible
    Demo Time!
    https://github.com/oktadev/auth0-java-rest-api-examples

    View full-size slide

  71. @mraible
    Stack Overflow Tags
    0
    45,000
    90,000
    135,000
    180,000
    October 17, 2023
    139
    144,464
    4,112
    1,704
    Micronaut Quarkus Spring Boot Helidon

    View full-size slide

  72. @mraible
    GitHub Stars
    0
    20,000
    40,000
    60,000
    80,000
    October 17, 2023
    3,200
    69,700
    12,400
    5,800
    Micronaut Quarkus Spring Boot Helidon

    View full-size slide

  73. https://star-history.t9t.io/#micronaut-projects/micronaut-core&quarkusio/quarkus&spring-projects/spring-boot&oracle/helidon
    GitHub Star Growth

    View full-size slide

  74. @mraible
    Jobs on Indeed (US)
    0
    2,500
    5,000
    October 17, 2023
    15
    3,985
    65
    48
    Micronaut Quarkus Spring Boot Helidon

    View full-size slide

  75. @mraible
    Twitter Followers
    0
    30,000
    60,000
    90,000
    120,000
    October 17, 2023
    4,531
    103,300
    18,400
    13,300
    Micronaut Quarkus Spring Boot Helidon

    View full-size slide

  76. @mraible
    JHipster Support 🤓
    Spring Boot 3 - JHipster 8.0.0-rc1, 8.0.0 coming soon!


    Micronaut blueprint - github.com/jhipster/generator-jhipster-micronaut


    - v2.0.0 for Micronaut 3, 19 releases, 20 contributors, 495 commits


    - v3.0.0 with Micronaut 4 with JHipster 8 is next!


    Quarkus blueprint - github.com/jhipster/generator-jhipster-quarkus


    - v2.0.0 for Quarkus 2, 7 releases, 18 contributors, 653 commits


    - v3.0.0 with Quarkus 3 is on the horizon!

    View full-size slide

  77. https://auth0.com/blog/full-stack-java-with-react-spring-boot-and-jhipster

    View full-size slide

  78. @mraible
    🏆 Quarkus provides the best developer joy and memory usage


    🚀 Micronaut is consistently competitive and 4.0 starts the fastest!


    🌱 Spring Boot has the strongest community, ecosystem, and growth


    🔮 Helidon has a lot of catching up to do


    ⚡ Spring Boot 3 not as fast as expected
    My Thoughts

    View full-size slide

  79. @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

    View full-size slide

  80. developer.auth0.com


    developer.okta.com


    @oktadev

    View full-size slide

  81. Subscribe to our Zero Index newsletter!
    a0.to/nl-signup/java

    View full-size slide

  82. git clone https://github.com/oktadeveloper/okta-spring-web
    fl
    ux-react-example.git
    https://github.com/oktadev/auth0-java-rest-api-examples
    Use the Source, Luke!

    View full-size slide

  83. Thanks!


    Keep in Touch


    raibledesigns.com


    @mraible


    Presentations


    speakerdeck.com/mraible


    Code


    github.com/oktadev
    developer.okta.com
    developer.auth0.com

    View full-size slide