The Chaos Incarnated: Micro-Quarkus Boot!

María Arias de Reyna Domínguez

@delawen@floss.social

Senior Software Engineer

Who am I?
  • Millenial Crazy Cat Lady
  • Free and Open Source Barbarian
  • Women in Tech Sorceress Coven
  • Software Engineer Wizard
  • GeoSpatial Paladin
    • 2009 Dijkstra A* Rogue
    • 2012 Metadata Ranger
    • 2013 OSGeo Charter Member
      • 2017-2019 OSGeo President
  • 2019 Integration Druid
  • 2020 Java Champion
  • 2024 OpenJDK Bard
The Java Ecosystem

The Foundations

  • Java
  • Frameworks and Libraries
    • Spring
    • Micronaut
    • Quarkus
    • Open Liberty
    • WildFly
    • Apache TomEE
    • Helidon

Why can't we be friends?

MicroProfile

Our Three Champions

We are going to explore

MicroProfile over

  • Spring Boot
  • Micronaut
  • Quarkus

Disclaimer

Agustín Ventura - VMWare

Spring Boot

  • "Standard" in the industry since forever (~2003)
  • Strong foundations, documentation, examples, use cases
  • Lots of experts
  • MicroProfile arrives late to Spring party

Micronaut

  • Close relationship with GraalVM (Oracle)
  • Has been up and about for a few years (2018)
  • Focus on Cloud Native and Microservices
  • MicroProfile is an important guest at Micronaut party

Quarkus

  • Optimization over Mandrel (Red Hat) and GraalVM
  • Has been up and about for a few years (2019)
  • Focus on Kubernetes and Optimization for the Cloud
  • MicroProfile is the basis of Quarkus party
Let's Get Dirty!

Let's Get Dirty!

  • Can we have an agnostic source code?
  • Can we seamlessly switch the framework and really keep working?
  • Is this a good idea at all?

Who is your Daddy?

Dependency management

Quarkus Spring Boot Micronaut
😊 🤠 😵

Hello REST API

                
                  package com.example;

                  import jakarta.ws.rs.GET;
                  import jakarta.ws.rs.Path;
                  import jakarta.ws.rs.Produces;
                  import jakarta.ws.rs.core.MediaType;
                  
                  
                  @Path("/hello")
                  public class HelloService {
                
                    @GET
                    @Produces(MediaType.TEXT_PLAIN)
                    public String hello() {
                      return "Hello from MicroProfile!";
                    }
                  
                  }
                  
                
              

Hello REST API

                
                  $ mvn clean quarkus:dev -Pquarkus
                  $ mvn clean spring-boot:run -Pspring
                  $ mvn clean mn:run -Pmicronaut
                
              

How picky are you?

Can I really have an agnostic source code?

Quarkus Spring Boot Micronaut
😊 😵 😵

And now for our next trick

I will need a database

                
                  
                    
                        com.h2database
                        h2
                        runtime
                    
                  
                
              

And now for our next trick

and a volunteer cat

                
                  @Entity
                  public class Cat implements Serializable {

                    @NotNull
                    @Column(name = "name", nullable = false)
                    private String name;

                    @Id
                    @GeneratedValue
                    private Long id;

                    public Long getId() {
                      return id;
                    }

                    public void setId(Long id) {
                      this.id = id;
                    }

                    public String getName() {
                      return name;
                    }

                    public void setName(String name) {
                      this.name = name;
                    }
                  }

                
              

And now for our next trick

that can be safely placed in a box

                
                  @Singleton
                  public class DatabaseResource {
                    @PersistenceContext
                    EntityManager entityManager;
                  
                    @Transactional
                    public void addCat(String name) {
                      Cat cat = new Cat();
                      cat.setName(name);
                      entityManager.persist(cat);
                    }
                    @Transactional
                    public List<Cat> getAllCats() {
                      CriteriaBuilder cb = entityManager.getCriteriaBuilder();
                      CriteriaQuery<Cat> cq = cb.createQuery(Cat.class);
                      Root<Cat> rootEntry = cq.from(Cat.class);
                      CriteriaQuery<Cat> all = cq.select(rootEntry);
                  
                      TypedQuery<Cat> allQuery = entityManager.createQuery(all);
                      return allQuery.getResultList();
                    }
                
              

And now for our next trick

and a service to accomodate them

                
                  @Path("/db")
                  public class PersistenceService {
                    @Inject
                    DatabaseResource databaseResource;

                    @GET  //For testing purposes
                    @Path("/cat/{name}")
                    @Produces(MediaType.TEXT_PLAIN)
                    @Transactional
                    public String addCat(@PathParam("name") String name) {
                      databaseResource.addCat(name);
                      return "Cat added with name " + name + " via GET.";
                    }

                    @POST
                    @Path("/cat/{name}")
                    @Produces(MediaType.TEXT_PLAIN)
                    @Transactional
                    public String addCatPost(@PathParam("name") String name) {
                      databaseResource.addCat(name);
                      return "Cat added with name " + name;
                    }

                    @GET
                    @Path("/cats")
                    @Produces(MediaType.APPLICATION_JSON)
                    @Transactional
                    public List<Cat> getCats() {
                      return databaseResource.getAllCats();
                    }
                  }

                
              

Are my properties clean?

Are they going to be mixed up?

Beware: This could be seen as a bug, not a feature!!

Quarkus Spring Boot Micronaut
😵/😊 😵/😊 😊/😵

How picky are you?

Can I really have an agnostic source code?

Quarkus Spring Boot Micronaut
😊 😵 😊

Summary

Quarkus Spring Boot Micronaut
Who is your Daddy? 😊 🤠 😵
How picky are you (REST)? 😊 😵 😵
Are my properties clean?* 😊/😵 😊/😵 😵/😊
How picky are you (Persistence)? 😊 😵 😊
Native

Let's go native!

I will need a database

              
                $ mvn clean install -Dquarkus.package.type=native -Pquarkus
                $ mvn clean package -Dpackaging=native-image -Pmicronaut
                $ mvn clean -Pnative spring-boot:build-image -Pspring
              
            
Questions?