DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Related

  • The Most Popular Technologies for Java Microservices Right Now
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  • How AI Is Rewriting Full-Stack Java Systems: Practical Patterns with Spring Boot, Kafka and WebSockets

Trending

  • RAG Is Not Enough: Advanced Retrieval Architectures Using Vertex AI Search on GCP
  • Leveraging Apache Flink Dashboard for Real-Time Data Processing in AWS Apache Flink Managed Service
  • Why Your DLP Policies Fall Short the Moment AI Agents Enter the Picture
  • Spring Boot Done Right: Lessons From a 400-Module Codebase
  1. DZone
  2. Coding
  3. Java
  4. Tackling Records in Spring Boot

Tackling Records in Spring Boot

Let’s take a look at several scenarios where Java records can help us increase readability and expressiveness by squeezing the homologous code.

By 
Anghel Leonard user avatar
Anghel Leonard
DZone Core CORE ·
May. 21, 24 · Tutorial
Likes (5)
Comment
Save
Tweet
Share
5.7K Views

Join the DZone community and get the full member experience.

Join For Free

Java records fit perfectly in Spring Boot applications. Let’s have several scenarios where Java records can help us increase readability and expressiveness by squeezing the homologous code.

Using Records in Controllers

Typically, a Spring Boot controller operates with simple POJO classes that carry our data back over the wire to the client. For instance, check out this simple controller endpoint returning a list of authors, including their books:

Java
 
@GetMapping("/authors")
public List<Author> fetchAuthors() {
  return bookstoreService.fetchAuthors();
}


Here, the Author (and Book) can be simple carriers of data written as POJOs. But, they can be replaced by records as well. Here it is:

Java
 
public record Book(String title, String isbn) {}
public record Author(String name, String genre, List<Book> books) {}


That’s all! The Jackson library (which is the default JSON library in Spring Boot) will automatically marshal instances of type Author/Book into JSON. In the bundled code, you can practice the complete example via the localhost:8080/authors endpoint address.

Using Records With Templates

Thymeleaf is probably the most used templating engine in Spring Boot applications. Thymeleaf pages (HTML pages) are typically populated with data carried by POJO classes, which means that Java records should work as well.

Let’s consider the previous Author and Book records, and the following controller endpoint:

Java
 
@GetMapping("/bookstore")
public String bookstorePage(Model model) {
  
  model.addAttribute("authors",
  bookstoreService.fetchAuthors());
  
  return "bookstore";
}


The List<Author> returned via fetchAuthors() is stored in the model under a variable named authors. This variable is used to populate bookstore.html as follows:

HTML
 
...
<ul th:each="author : ${authors}">
  <li th:text="${author.name} + ' (' + ${author.genre} + ')'" />
  <ul th:each="book : ${author.books}">
    <li th:text="${book.title}" />
  </ul>
</ul>
...


Done! You can check out the application Java Coding Problems SE.

Using Records for Configuration

Let’s assume that in application.properties we have the following two properties (they could be expressed in YAML as well):

Properties files
 
bookstore.bestseller.author=Joana Nimar
bookstore.bestseller.book=Prague history


Spring Boot maps such properties to POJO via @ConfigurationProperties. But, a record can be used as well. For instance, these properties can be mapped to the BestSellerConfig record as follows:

Java
 
@ConfigurationProperties(prefix = "bookstore.bestseller")
public record BestSellerConfig(String author, String book) {}


Next, in BookstoreService (a typical Spring Boot service), we can inject BestSellerConfig and call its accessors:

Java
 
@Service
public class BookstoreService {
  
  private final BestSellerConfig bestSeller;

  public BookstoreService(BestSellerConfig bestSeller) {
    this.bestSeller = bestSeller;
  }
  
  public String fetchBestSeller() {
     return bestSeller.author() + " | " + bestSeller.book();
  }
}


In the bundled code, we have added a controller that uses this service as well.

Record and Dependency Injection

In the previous examples, we have injected the BookstoreService service into BookstoreController using the typical mechanism provided by SpringBoot – dependency injection via constructor (it can be done via @Autowired as well):

Java
 
@RestController
public class BookstoreController {
  
  private final BookstoreService bookstoreService;
  
  public BookstoreController(BookstoreService bookstoreService) {
    this.bookstoreService = bookstoreService;
  }
  
  @GetMapping("/authors")
  public List<Author> fetchAuthors() {
    return bookstoreService.fetchAuthors();
  }
}


But, we can compact this class by re-writing it as a record as follows:

Java
 
@RestController
public record BookstoreController(BookstoreService bookstoreService) {
  
  @GetMapping("/authors")
  public List<Author> fetchAuthors() {
    return bookstoreService.fetchAuthors();
  }
}


The canonical constructor of this record will be the same as our explicit constructor. The application is available on GitHub.

Feel free to challenge yourself to find more use cases of Java records in Spring Boot applications.

Dependency injection Java (programming language) Spring Boot

Opinions expressed by DZone contributors are their own.

Related

  • The Most Popular Technologies for Java Microservices Right Now
  • Zero-Downtime Deployments for Java Apps on Kubernetes
  • OpenAPI From Code With Spring and Java: A Recipe for Your CI
  • How AI Is Rewriting Full-Stack Java Systems: Practical Patterns with Spring Boot, Kafka and WebSockets

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

  • RSS
  • X
  • Facebook

ABOUT US

  • About DZone
  • Support and feedback
  • Community research

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 215
  • Nashville, TN 37211
  • [email protected]

Let's be friends:

  • RSS
  • X
  • Facebook