Spring Data Cosmos sample for a multi-tenanted app where each tenant has its own Azure Cosmos DB container.
- This sample only work with Spring Boot 3 This sample application fetches the value of the tenant from request header (TenantId). In a real-world application, it is up to you how to identify this while keeping your application secure. For example, you may want to fetch the identifier from a cookie, or other header name. The approach of assigning a container (or database) to each tenant may be useful if it is necessary to strictly isolate performance for each tenant. However, you should consider the trade-offs in taking this approach. Review our article on Multitenancy and Azure Cosmos DB for more guidance.
Note: this is a contrived sample in terms of the data model, and does not reflect any recommendations for how to model any application in particular. It is intended purely to illustrate how to maintain a container-per-tenant isolation model using Spring Data for Azure Cosmos DB, where containers for each tenant are created/referenced dynamically (on-the-fly) rather than being hardcoded at project startup.
Java Development Kit 8
.- Apache Maven.
- Create an active Azure account. If you don't have one, you can sign up for a free account. Alternatively, you can use the Azure Cosmos DB Emulator for development and testing. As emulator https certificate is self signed, you need to import its certificate to java trusted cert store, explained here.
- Apache Maven.
- The app uses environment variables
ACCOUNT_HOST
andACCOUNT_KEY
. Make sure these environment variables exist, and are set to your Azure Cosmos DB accountURI
andPRIMARY KEY
respectively.
- git clone https://github.com/Azure-Samples/azure-spring-boot-samples.git
- cd cosmos/azure-spring-data-cosmos/cosmos-multi-tenant-samples/tenant-by-container
- start the application:
mvn spring-boot:run
- Send a request to the web service from a linux based command line (or you can use postman):
curl -s -d '{"firstName":"Theo","lastName":"van Kraay"}' -H "Content-Type: application/json" -H "TenantId: theo" -H "TenantTier: standard" -X POST http://localhost:8080/users
- Create an Order:
curl -s -d '{"orderDetail":"Order no.1","lastName":"Brown"}' -H "Content-Type: application/json" -H "TenantId: mark" -H "TenantTier: premium" -X POST http://localhost:8080/orders
- You should see containers named by each tenant created in Cosmos DB, with co-located entities of
User
andOrder
, identifiable by atype
field in the document.
- The application is a simple CRUD REST web service which creates
User
andOrder
entries in each tenant (co-located in the same container), and makes use ofazure-spring-data-cosmos
for Azure Cosmos DB NoSQL API. - The application captures a http request header of
TenantId
. This is used to check if the corresponding tenant id exists. If it does not, the container will be created. - The application also captures a http request header of
TenantTier
. This is used to determine whether to set dedicated throughput for the container ("premium") or use the shared throughput for the database. - The Java classes with functionality for capturing
TenantId
andTenantTier
, and referencing and/or creating tenant containers byTenantId
, are in the tenant folder. - CRUD operations are performed in
UserController
andOrderController
using corresponding SpringRepository
APIs. The two entitiesOrder
andUser
are co-located in the same container, and differentiated using atype
field in the record.
Please refer to azure spring data cosmos for NoSql api source code for more information.