Quarkus Roq Data

Quarkus Roq Data is a Quarkus extension that register JSON/YAML files as CDI beans, and available from Qute templates, in a type-safe way in your project.

Roq Data is already included as part of the Roq Static Site Generator extension io.quarkiverse.roq:quarkus-roq, Follow Standalone installation section to use it standalone.

Data Mapping

You can add JSON or YAML files to your project’s data directory.

The data file can use .json, .yml, or .yaml extensions.
mountain.json
{
    "name": "Lhotse",
    "elevation": 8516
}

To use the data in your Java code, you have two options:

1. Use a Java class mapping.

Mountain.java
import io.quarkiverse.roq.data.runtime.annotations.DataMapping;

@DataMapping("mountain") (1)
public record Mountain(String name, Integer elevation) {}
1 The filename of the data file without the extension.

Then inject the Mountain record into a resource class.

Resource.java
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/site")
public class Resource {

    @Inject
    Mountain mountain;

    @GET
    public String getMountain() {
        return mountain.toString();
    }
}

Access the resource using the following URL: http://localhost:8080/site. The output should be Quarkus Site - Quarkus Site generated by Roq.

2. Use JsonObject dynamic mapping

It is also possible to directly access the data without having a class mapping. In this case you can inject a named io.vertx.core.json.JsonObject in your code:

Resource.java
import jakarta.inject.Inject;
import jakarta.inject.Named;import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/site")
public class Resource {

    @Inject
    @Named("mountain") (1)
    JsonObject mountain;

    @GET
    public String getMountain() {
        return mountain.toString();
    }
}
1 The filename of the data file without the extension.

Mapping data file as a array

If your data file root element is an array.

mountains.json
[
    {
        "name": "Lhotse",
        "elevation": 8516
    },
    {
        "name": "Everest",
        "elevation": 8849
    }
]

You also have two options to map it.

1. Use a parent Java class mapping.

You could create a parent record as shown below:

Mountains.java
import java.util.List;
import io.quarkiverse.roq.data.runtime.annotations.DataMapping;

@DataMapping(value = "mountains", parentArray = true) (1)
public record Mountains(List<Mountain> list) { (2)

}
1 The parentArray attribute is set to true to indicate that the root element of the data file is an array.
2 The class aimed to map the data file must have a constructor that accepts a single parameter of type List<T>, where T is the type of the elements in the array.
The class annotated with @DataMapping(parentArray=true) must have a constructor that accepts a single parameter of type List<T>, where T is the type of the elements in the array.

With the above configuration, the Mountains record will have a list of Mountain records and can be injected via CDI.

2. Use JsonArray dynamic mapping

It is also possible to directly access the data without having a class mapping. In this case you can inject a named io.vertx.core.json.JsonArray in your code:

Resource.java
import jakarta.inject.Inject;
import jakarta.inject.Named;import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;

@Path("/site")
public class Resource {

    @Inject
    @Named("mountains") (1)
    JsonArray mountains;

    @GET
    public String getMountains() {
        return mountains.toString();
    }
}
1 The filename of the data file without the extension.

From a Qute template

Since generated data beans are named, it is possible to access them from any Qute template:

{#for mountain in cdi:mountains}
  <li>{mountains.name}: {mountains.elevation}</li> (1)
{/for}
1 A Value Resolver already exists for JsonObject allowing you to directly access attributes.
For type-safety, use a @DataMapping bean instead and access it using the Qute cdi namespace.

Standalone installation

It is included as part of the Roq Static Site Generator extension io.quarkiverse.roq:quarkus-roq. You can also use it standalone.

If you want to use this extension standalone, you need to add the io.quarkiverse.roq:quarkus-roq-data extension first to your build file.

For instance, with Maven, add the following dependency to your POM file:

<dependency>
    <groupId>io.quarkiverse.roq</groupId>
    <artifactId>quarkus-roq-data</artifactId>
    <version>1.0.4</version>
</dependency>

Extension Configuration Reference

Configuration property fixed at build time - All other configuration properties are overridable at runtime

Configuration property

Type

Default

The location of the Roq data files relative to the quarkus.roq.dir.

Environment variable: QUARKUS_ROQ_DATA_DIR

string

data

Whether to enforce the use of a bean for each data file.
With this option enabled, when a record is annotated with DataMapping, a bean will be created and populated with the data from the file.

Environment variable: QUARKUS_ROQ_DATA_ENFORCE_BEAN

boolean

false

Log data beans as info during build

Environment variable: QUARKUS_ROQ_DATA_LOG_DATA_BEANS

boolean

true