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
Slide 2
Slide 2 text
@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
Slide 3
Slide 3 text
No content
Slide 4
Slide 4 text
No content
Slide 5
Slide 5 text
No content
Slide 6
Slide 6 text
developer.okta.com
Slide 7
Slide 7 text
developer.auth0.com
Slide 8
Slide 8 text
@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
Slide 9
Slide 9 text
@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
Slide 10
Slide 10 text
@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
Slide 11
Slide 11 text
@mraible
Get Started with Java 21
Better yet, use SDKMAN!
curl -s https://get.sdkman.io | bash
sdk install java 21-open
Slide 12
Slide 12 text
Java Releases and Features
Slide 13
Slide 13 text
https://developer.okta.com/blog/2020/01/09/java-rest-api-showdown
Build REST APIs with Java
Install HTTPie (a better cURL)
$ install httpie
https://httpie.org
Slide 24
Slide 24 text
Test Micronaut with HTTPie
https://httpie.org
gradle run
http :8080/hello
TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...
http :8080/hello Authorization:"Bearer $TOKEN"
Slide 25
Slide 25 text
Verify Micronaut API with HTTPie
Slide 26
Slide 26 text
@mraible
Get Started with Quarkus
sdk install quarkus
quarkus create app com.okta.rest:quarkus \
--extension="smallrye-jwt,resteasy-reactive"
--gradle
Slide 27
Slide 27 text
@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
Test Quarkus with HTTPie
https://httpie.org
gradle --console=plain quarkusDev
http :8080/hello
TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...
http :8080/hello Authorization:"Bearer $TOKEN"
Slide 34
Slide 34 text
Verify Quarkus API with HTTPie
Slide 35
Slide 35 text
@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 -
Slide 36
Slide 36 text
https://start.spring.io
https://start.spring.io
Slide 37
Slide 37 text
@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
Slide 38
Slide 38 text
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() + "!";
}
}
Slide 39
Slide 39 text
The Okta Spring Boot Starter
https://github.com/okta/okta-spring-boot
okta.oauth2.issuer=https://dev-1337.us.auth0.com
Slide 40
Slide 40 text
Test Spring Boot with HTTPie
https://httpie.org
gradle bootRun
http :8080/hello
TOKEN=eyJraWQiOiJxOE1QMjFNNHZCVmxOSkxGbFFWNlN...
http :8080/hello Authorization:"Bearer $TOKEN"
Slide 41
Slide 41 text
Verify Spring Boot API with HTTPie
Slide 42
Slide 42 text
@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
@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
Slide 52
Slide 52 text
@mraible
Secure your API with OAuth 2.1
https://aaronparecki.com/2019/12/12/21/its-time-for-oauth-2-dot-1
Slide 53
Slide 53 text
@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
Slide 54
Slide 54 text
@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
Slide 55
Slide 55 text
What about testing?
Slide 56
Slide 56 text
@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"]
Slide 57
Slide 57 text
@mraible
Build with Docker
Build your image
docker build -t .
Run your image
docker run -it -p 8080:8080
Slide 58
Slide 58 text
@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
Slide 59
Slide 59 text
@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"
Slide 60
Slide 60 text
@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
Slide 61
Slide 61 text
@mraible
Build with Docker
Helidon generates three Docker-related files
Dockerfile
Dockerfile.jlink
Dockerfile.native
Helidon + Jib
Not available
Slide 62
Slide 62 text
@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
Slide 63
Slide 63 text
@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
Slide 64
Slide 64 text
@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'
}
Slide 65
Slide 65 text
@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
Slide 66
Slide 66 text
@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
Slide 67
Slide 67 text
@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)
@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
@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
Slide 84
Slide 84 text
@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
Slide 85
Slide 85 text
developer.auth0.com
developer.okta.com
@oktadev
Slide 86
Slide 86 text
Subscribe to our Zero Index newsletter!
a0.to/nl-signup/java
Slide 87
Slide 87 text
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!