avatar

Bhuwan Upadhyay

Talks all about software engineering

Published on

Setting up a Quarkus project

Authors

In this post, we will see how to set up a Quarkus project to develop CRUD REST APIs.

Install Quarkus CLI

Quarkus provides a CLI tool to create and manage Quarkus projects. You can install by using sdkman, run the following command:

sdk install quarkus

Check the installation by running the following command:

quarkus --version

Create a Quarkus project

To create a Quarkus project, run the following command:

quarkus create app --maven --java=11 -o setting-up-a-quarkus-project

This will create a new project in the setting-up-a-quarkus-project directory. To change directory to the project directory, run the following command:

cd setting-up-a-quarkus-project

Run the application

To run the application, run the following command:

quarkus dev

By default, the application will run on port 8080. You can access the application by visiting http://localhost:8080/.

Create a REST endpoint

To create a REST endpoint, create a new file AwesomeResource.java with the following content:

package org.acme.quickstart;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
@Path("/awesome")
public class AwesomeResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String awesome() {
        return "awesome";
    }
}

You can access the endpoint by visiting http://localhost:8080/awesome. This will return awesome.

Add a database, orm, jsonb extensions

Quarkus provides a lot of extensions to add more features to the application. For example, to add the PostgreSQL, ORM and JSONB extension, run the following command:

quarkus ext add io.quarkus:quarkus-jdbc-postgresql
quarkus ext add io.quarkus:quarkus-hibernate-orm
quarkus ext add io.quarkus:quarkus-resteasy-reactive-jsonb

This will add the following dependency to the pom.xml file:

<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-hibernate-orm</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-jdbc-postgresql</artifactId>
</dependency>
<dependency>
    <groupId>io.quarkus</groupId>
    <artifactId>quarkus-resteasy-reactive-jsonb</artifactId>
</dependency>

To configure the database, add the following properties to the application.properties file:

quarkus.datasource.db-kind=postgresql 
quarkus.datasource.username=quarkus
quarkus.datasource.password=quarkus
quarkus.datasource.jdbc.url=jdbc:postgresql://localhost:5432/quarkus
quarkus.datasource.jdbc.max-size=16

To launch docker postgresql container, run the following command:

docker run --ulimit memlock=-1:-1 -it --rm=true \
    --name quarkus_test \
    -e POSTGRES_USER=quarkus \
    -e POSTGRES_PASSWORD=quarkus \
    -e POSTGRES_DB=quarkus \
    -p 5432:5432 postgres:11.5

Create an entity

To create an entity, create a new file Awesome.java with the following content:

package org.acme.quickstart;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
@Entity
public class Awesome {

    @javax.persistence.Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    
    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;
    }
}

Create a service

To create a service, create a new file AwesomeService.java with the following content:

package org.acme.quickstart;
import javax.enterprise.context.ApplicationScoped;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.transaction.Transactional;
import java.util.List;
@ApplicationScoped // to make the service a CDI bean
@Transactional // to ensure that the transaction is committed
public class AwesomeService {

    @PersistenceContext
    EntityManager entityManager;
    public Awesome getAwesome(Long id) {
        return entityManager.find(Awesome.class, id);
    }

    public Awesome createAwesome(Awesome awesome) {
        entityManager.persist(awesome);
        return awesome;
    }

    public Awesome updateAwesome(Long id, Awesome awesome) {
        Awesome awesomeToUpdate = entityManager.find(Awesome.class, id);
        awesomeToUpdate.setName(awesome.getName());
        return awesomeToUpdate;
    }

    public void deleteAwesome(Long id) {
        Awesome awesomeToDelete = entityManager.find(Awesome.class, id);
        entityManager.remove(awesomeToDelete);
    }

    public List<Awesome> listAll() {
        return entityManager.createQuery("FROM Awesome", Awesome.class)
                            .getResultList();
    }
}

REST endpoints to perform CRUD operations

To add a REST endpoint to perform CRUD operations on a database, update the AwesomeResource.java file with the following content:

package org.acme.quickstart;
import javax.inject.Inject;
import javax.ws.rs.*;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import java.util.List;
@Path("/awesome")
public class AwesomeResource {

    @Inject
    AwesomeService awesomeService;
    
    // Add a REST endpoint to find record by id
    @GET
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response getAwesome(@PathParam(value = "id") Long id) {
        Awesome awesome = awesomeService.getAwesome(id);
        return Response.ok(awesome).build();
    }

    // Add a REST endpoint to create a record in the database
    @POST
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response createAwesome(Awesome awesome) {
        Awesome newAwesome = awesomeService.createAwesome(awesome);
        return Response.ok(newAwesome).build();
    }

    // Add a REST endpoint to update a record in the database
    @PUT
    @Path("/{id}")
    @Consumes(MediaType.APPLICATION_JSON)
    @Produces(MediaType.APPLICATION_JSON)
    public Response updateAwesome(@PathParam(value = "id") Long id, Awesome awesome) {
        Awesome updatedAwesome = awesomeService.updateAwesome(id, awesome);
        return Response.ok(updatedAwesome).build();
    }

    // Add a REST endpoint to delete a record in the database
    @DELETE
    @Path("/{id}")
    @Produces(MediaType.APPLICATION_JSON)
    public Response deleteAwesome(@PathParam(value = "id") Long id) {
        awesomeService.deleteAwesome(id);
        return Response.ok().build();
    }

    // Add a REST endpoint to list all records in the database
    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response listAll() {
        List<Awesome> awesomeList = awesomeService.listAll();
        return Response.ok(awesomeList).build();
    }
}

You can access the REST endpoints by visiting the following URLs:

  • http://localhost:8080/awesome - POST
curl -X POST http://localhost:8080/awesome -H 'Content-Type: application/json' \
  -d '{
    "name": "Awesome"
}'
  • http://localhost:8080/awesome - GET list all
curl -X GET http://localhost:8080/awesome -H 'Content-Type: application/json'

Set entity id as environment variable:

export entity_id=$(curl -X GET http://localhost:8080/awesome -H 'Content-Type: application/json' | jq -r '.[].id' | head -1)
echo "entity_id=$entity_id"
  • http://localhost:8080/awesome/$entity_id - GET by id
curl -X GET http://localhost:8080/awesome/$entity_id -H 'Content-Type: application/json'
  • http://localhost:8080/awesome/$entity_id - PUT update by id
curl -X PUT http://localhost:8080/awesome/$entity_id -H 'Content-Type: application/json' \
  -d '{
    "name": "Awesome 2"
}'
  • http://localhost:8080/awesome/$entity_id - DELETE by id
curl -X DELETE http://localhost:8080/awesome/$entity_id -H 'Content-Type: application/json'

Github repository

You can find the source code for this tutorial on Github: setting-up-a-quarkus-project.

Conclusion

In this tutorial, you learned how to create a REST API with Quarkus. You also learned how to add a database extension and perform CRUD operations on a database.

References