Spring Boot with Spring Data MongoDB

TeselaDB

TeselaDB

TeselaDB team

35 minIntermediate

An orders API with Spring Boot 4 and a Spring Data repository that saves to TeselaDB over TLS.

Spring Data MongoDB talks to the database through the official Java driver, so your documents and your repositories work with TeselaDB unchanged. Here you set up an orders API and connect it to the cluster over TLS.

What you will build

A Spring Boot 4 application with an Order document, a repository with a derived query and a controller with POST /orders, GET /orders/{id} and GET /orders?customer=.

Requirements

  • Java 21 or later.
  • A TeselaDB cluster, its CA (pki/ca.pem) and a user with readWrite on the shop database.
  • The connection string in the TESELADB_URI environment variable, with tls=true and without tlsCAFile.

1. Create the project

Generate a Maven project for Java 21 with the web and Spring Data MongoDB modules from start.spring.io, and unzip it in the orders folder:

Shell
curl -s https://start.spring.io/starter.zip -d dependencies=web,data-mongodb -d type=maven-project \
  -d javaVersion=21 -d groupId=com.example -d artifactId=orders -o orders.zip
unzip orders.zip -d orders && cd orders

2. Connect it to TeselaDB

In src/main/resources/application.properties. The cluster CA goes in a Spring Boot SSL bundle, which the MongoDB client uses as its trust store. In Spring Boot 3, the property for the string is spring.data.mongodb.uri:

spring.mongodb.uri=${TESELADB_URI}
spring.ssl.bundle.pem.teseladb.truststore.certificate=file:./ca.pem
spring.mongodb.ssl.bundle=teseladb

3. Write the document, the repository and the controller

In src/main/java/com/example/orders/. Spring Data builds the query of findByCustomer from its name:

Java
package com.example.orders;

import java.time.Instant;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document("orders")
public record Order(@Id String id, String customer, double total, Instant createdAt) {}
Java
package com.example.orders;

import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;

public interface OrderRepository extends MongoRepository<Order, String> {
  List<Order> findByCustomer(String customer);
}
Java
package com.example.orders;

import java.time.Instant;
import java.util.List;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/orders")
public class OrderController {
  private final OrderRepository orders;

  public OrderController(OrderRepository orders) {
    this.orders = orders;
  }

  @PostMapping
  @ResponseStatus(HttpStatus.CREATED)
  public Order create(@RequestBody Order order) {
    return orders.save(new Order(null, order.customer(), order.total(), Instant.now()));
  }

  @GetMapping("/{id}")
  public ResponseEntity<Order> read(@PathVariable String id) {
    return ResponseEntity.of(orders.findById(id));
  }

  @GetMapping
  public List<Order> byCustomer(@RequestParam String customer) {
    return orders.findByCustomer(customer);
  }
}

Try it

Start the application with ./mvnw spring-boot:run. Then, in another terminal, create an order for Ana with a total of 30 and look it up by customer with GET /orders?customer=, which runs the derived query of findByCustomer in the repository:

Shell
./mvnw spring-boot:run
curl -s -X POST localhost:8080/orders -H "content-type: application/json" -d '{"customer":"Ana","total":30}'
curl -s "localhost:8080/orders?customer=Ana"

The second command returns a list with Ana's order, with its id and its creation date.

Clean up

JavaScript
db.getSiblingDB("shop").orders.deleteMany({ customer: "Ana" });

Stop the application with Ctrl+C and run this command in mongosh to delete the test orders, all of them with Ana as the customer.

Next steps

  • Java, with the Java driver without Spring.
  • ODMs and ORMs, with Mongoose and Beanie.