Quarkus Azure Cosmos DB Extension
Quarkus Azure Services Extensions are developed and supported by Microsoft as part of their commitment to Open Standard Enterprise Java. For more information, see Jakarta EE on Azure.
Azure Cosmos DB is a fully managed NoSQL, relational, and vector database.
This extension allows you to do the full set of data manipulations supported by Azure Cosmos DB by injecting a com.azure.cosmos.CosmosClient
or com.azure.cosmos.CosmosAsyncClient
object inside your Quarkus application.
This is a step by step guide on how to use the Quarkus Azure Cosmos DB extension. If you’re looking for a complete code sample, you can find it in the Azure Cosmos DB sample.
Installation
Add a dependncy on io.quarkiverse.azureservices:quarkus-azure-cosmos
.
For instance, with Maven, add the following dependency to your POM file:
<dependency>
<groupId>io.quarkiverse.azureservices</groupId>
<artifactId>quarkus-azure-cosmos</artifactId>
<version>1.0.7</version>
</dependency>
How to Use It
Once you have added the extension to your project, follow the next steps, so you can inject com.azure.cosmos.CosmosClient
or com.azure.cosmos.CosmosAsyncClient
object in your application to read/write items from/to the specified database and container.
Setup your Azure Environment
First thing first.
For this sample to work, you need to have an Azure account as well as Azure CLI installed.
The Azure CLI is available to install in Windows, macOS and GNU/Linux environments.
Checkout the installation guide.
Then, you need an Azure subscription and log into it by using the az login
command.
You can run az version
to find the version and az upgrade
to upgrade to the latest version.
Create an Azure resource group with the az group create command. A resource group is a logical container into which Azure resources are deployed and managed.
az group create \
--name rg-quarkus-azure-cosmos \
--location westus
Create an Azure Cosmos DB account with the following command:
az cosmosdb create \
-n kvquarkusazurecosmos080824 \
-g rg-quarkus-azure-cosmos \
--default-consistency-level Session \
--locations regionName='West US' failoverPriority=0 isZoneRedundant=False
If you log into the Azure portal, you can see the resource group and the Azure Cosmos DB account you created.
Next, assign the Cosmos DB Built-in Data Contributor
role to the signed-in user, so that the sample application can do data plane CRUD operations.
az ad signed-in-user show --query id -o tsv \
| az cosmosdb sql role assignment create \
--account-name kvquarkusazurecosmos080824 \
--resource-group rg-quarkus-azure-cosmos \
--scope "/" \
--principal-id @- \
--role-definition-id 00000000-0000-0000-0000-000000000002
Notice that you cannot use any Azure Cosmos DB data plane SDK to authenticate management operations with a Microsoft Entra identity, you need to create database and container manually.
Run the following commands to create a database demodb
and a container democontainer
using Azure CLI.
az cosmosdb sql database create \
-a kvquarkusazurecosmos080824 \
-g rg-quarkus-azure-cosmos \
-n demodb
az cosmosdb sql container create \
-a kvquarkusazurecosmos080824 \
-g rg-quarkus-azure-cosmos \
-d demodb \
-n democontainer \
-p "/id"
Configure the Azure Cosmos DB Client
As you can see below in the Extension Configuration Reference section, the property quarkus.azure.cosmos.endpoint
is required if the extension is enabled.
To get the endpoint of the Azure Cosmos DB account, execute the following Azure CLI command:
export QUARKUS_AZURE_COSMOS_ENDPOINT=$(az cosmosdb show \
-n kvquarkusazurecosmos080824 \
-g rg-quarkus-azure-cosmos \
--query documentEndpoint -o tsv)
echo "QUARKUS_AZURE_COSMOS_ENDPOINT is: ${QUARKUS_AZURE_COSMOS_ENDPOINT}"
Because Quarkus implements the [MicroProfile Config specification](https://microprofile.io/project/eclipse/microprofile-config), the value of the environment variable QUARKUS_AZURE_COSMOS_ENDPOINT
is read as if the property quarkus.azure.cosmos.endpoint
were set in the application.properties
file.
Although technically both approaches work, using environment variable is recommended and more secure as there’s no risk of committing the connection string to source control.
Inject the Azure Cosmos DB Client
Now that your Azure environment is ready and you have configured the extension, you can @Inject
the com.azure.cosmos.CosmosClient
object in your imperative application or @Inject
the com.azure.cosmos.CosmosAsyncClient
object in your reactive application, so you can interact with Azure Cosmos DB. For complete API see [the Azure SDK for Java Reference Documentation](https://javadoc.io/doc/com.azure/azure-cosmos/latest/).
Use the CosmosClient in an imperative application
The createItem
method first creates the item with request payload in the specified database and container of the Azure Cosmos DB account.
The getItem
method reads the item with the id from the specified database and container of the Azure Cosmos DB account.
@Path("/quarkus-azure-cosmos")
@ApplicationScoped
public class CosmosResource {
@Inject
CosmosClient cosmosClient;
@Path("/{database}/{container}")
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Response createItem(
@PathParam("database") String database,
@PathParam("container") String container,
Item body,
@Context UriInfo uriInfo) {
cosmosClient.getDatabase(database).getContainer(container).upsertItem(body);
return Response.created(uriInfo.getAbsolutePathBuilder().path(body.getId()).build()).build();
}
@Path("/{database}/{container}/{itemId}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getItem(
@PathParam("database") String database,
@PathParam("container") String container,
@PathParam("itemId") String itemId) {
CosmosItemResponse<Item> item = cosmosClient.getDatabase(database).getContainer(container).readItem(itemId, new PartitionKey(itemId),
Item.class);
return Response.ok().entity(item.getItem()).build();
}
}
To test this sample you can run the following cURL commands after the application is started:
-
curl http://localhost:8080/quarkus-azure-cosmos/demodb/democontainer -X POST -d '{"id": "1", "name": "sync-item"}' -H "Content-Type: application/json"
-
curl http://localhost:8080/quarkus-azure-cosmos/demodb/democontainer/1 -X GET
You can go back to the Azure portal, open Data Explorer of the Azure Cosmos DB account, and see the item that you’ve created.
Use the CosmosAsyncClient in a reactive application
Similarly, the createItem
method first asynchronously creates the item with request payload in the specified database and container of the Azure Cosmos DB account.
The getItem
method asynchronously reads the item with the id from the specified database and container of the Azure Cosmos DB account. The sample makes heavy use of Project Reactor. For more information see [Reactor Reference Guide](https://projectreactor.io/docs/core/release/reference/).
@Path("/quarkus-azure-cosmos-async")
@ApplicationScoped
public class CosmosAsyncResource {
@Inject
CosmosAsyncClient cosmosAsyncClient;
@POST
@Consumes(MediaType.APPLICATION_JSON)
public Uni<Response> createItem(
@PathParam("database") String database,
@PathParam("container") String container,
Item body,
@Context UriInfo uriInfo) {
Mono<CosmosItemResponse<Item>> response = cosmosAsyncClient.getDatabase(database).getContainer(container).upsertItem(body);
return Uni.createFrom().completionStage(response.toFuture())
.map(it -> Response.created(uriInfo.getAbsolutePathBuilder().path(body.getId()).build()).build());
}
@Path("/{database}/{container}/{itemId}")
@GET
@Produces(MediaType.APPLICATION_JSON)
public Uni<Response> getItem(
@PathParam("database") String database,
@PathParam("container") String container,
@PathParam("itemId") String itemId) {
Mono<CosmosItemResponse<Item>> item = cosmosAsyncClient.getDatabase(database).getContainer(container).readItem(itemId, new PartitionKey(itemId), Item.class);
return Uni.createFrom().completionStage(item.toFuture())
.map(it -> Response.ok().entity(it.getItem()).build());
}
}
To test this sample you can run the following cURL commands after the application is started:
-
curl http://localhost:8080/quarkus-azure-cosmos-async/demodb/democontainer -X POST -d '{"id": "2", "name": "async-item"}' -H "Content-Type: application/json"
-
curl http://localhost:8080/quarkus-azure-cosmos-async/demodb/democontainer/2 -X GET
You can go back to the Azure portal, open Data Explorer of the Azure Cosmos DB account, and see the item that you’ve created.