Spring RestClient Example
In this section, we'll learn how to use RestClient to perform HTTP requests in a Spring Boot application.
Spring Framework 6.1 introduced the RestClient API. As we all know, Spring Framework 6.1 is part of Spring Boot version 3.2.
About RestClient
RestClient is a synchronous client to perform HTTP requests. It is a higher-order API since it performs HTTP requests by using an HTTP client library like the JDK HttpClient, Apache HttpComponents, and others.
We can use the Spring RestClient interface to perform HTTP requests using a fluent API. Fluent APIs are designed to make the code more readable and therefore easier to use. Wiring objects together using method chaining helps accomplish these readability and usability goals.
Creating a RestClient
In this example we are creating RestClient using static method create(String url).
@Configuration
public class RestClientConfig {
@Value("${user.base.url}")
String baseUrl;
@Bean
RestClient restClient() {
return RestClient.create(baseUrl);
}
}
Other available options to create RestClient are listed below:
- Using the builder() method which allows us to set default headers, interceptors, error handlers etc.
- We can initialize a RestClient with an existing RestTemplate's configuration by using create(RestTemplate).
- We can get a RestClient builder based on the RestTemplate's configuration by using builder(RestTemplate).
- The default rest client is delegated to by the create() method.
HTTP GET: Get all Users
To create a GET request to the given URL, use the restClient.get() method.
public List<User> getAllUsers() {
List<User> users = restClient.get()
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(List.class);
logger.info("List of users: " + users);
return users;
}
HTTP GET: Get all Users as ResponseEntity
The method toEntity returns a ResponseEntity if we need to inspect the response headers or response status code.
public List<User> getAllUsersAsResponseEntity() {
ResponseEntity<List> responseEntity = restClient.get()
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.toEntity(List.class);
logger.info("List of users: " + responseEntity.getBody());
if (responseEntity.getStatusCode().is2xxSuccessful()) {
logger.info("Fetched: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
HTTP GET: Find User by Id and Handling Errors
After the call to retreive method, we are handling errors using onStatus() method. Or, you can use defaultStatusHandler() method.
public User findById(Long id) {
User user = restClient.get()
.uri("/{id}",id)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError,
(req, res) -> {
logger.error("Failed to get User: " + res.getStatusText());
logger.error("Failed to get User:" + res.getStatusCode());
}
)
.onStatus(HttpStatusCode::is5xxServerError,
(req, res) -> {
//TODO
})
.body(User.class);
logger.info("User: " + user);
return user;
}
HTTP GET: Find User by Id using exchange() API
exchange() method gives access to HttpRequest and HttpResponse objects. It allowing us to perform error handling as well.
public User findByIdWithExchangeMethod(Long id) {
User user = restClient.get()
.uri("/{id}", id)
.accept(MediaType.APPLICATION_JSON)
.exchange((request, response) -> {
if (response.getStatusCode().is4xxClientError()) {
logger.error("Failed to get User: " + response.getStatusText());
logger.error("Failed to get User:" + response.getStatusCode());
return null;
}
else {
ObjectMapper mapper = new ObjectMapper();
User _user = mapper.readValue(response.getBody(), User.class);
logger.error("User: " + _user);
return _user;
}
});
return user;
}
HTTP POST: Create User
To create a POST request to the given URL, use the restClient.post() method.
public User createUser(User user) {
ResponseEntity<User> responseEntity = restClient.post()
.accept(MediaType.APPLICATION_JSON)
.body(user)
.retrieve()
.toEntity(User.class);
logger.info("User: " + responseEntity.getBody());
if (responseEntity.getStatusCode().is2xxSuccessful()) {
logger.info("Created: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
HTTP PUT: Update User
To create a PUT request to the given URL, use the restClient.put() method.
public User updateUser(User user, Long id) {
ResponseEntity<User> responseEntity = restClient.put()
.uri("/{id}",id)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(user)
.retrieve()
.toEntity(User.class);
logger.info("User: " + responseEntity.getBody());
if (responseEntity.getStatusCode().is2xxSuccessful()) {
logger.info("Updated: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
HTTP DELETE: Delete User
To create a DELETE request to the given URL, use the restClient.delete() method.
public void deleteUser(Long id) {
ResponseEntity response = restClient.delete()
.uri("/{id}",id)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError,
(req, res) -> {
logger.error("Couldn't delete:" + res.getStatusText());
logger.error("Couldn't delete:" + res.getStatusCode());
ObjectMapper mapper = new ObjectMapper();
ErrorMessage message = mapper.readValue(res.getBody(),
ErrorMessage.class);
logger.error("Couldn't delete:" + message);
}
)
.onStatus(HttpStatusCode::is5xxServerError,
(req, res) -> {
//TODO
}
)
.toBodilessEntity();
if (response.getStatusCode().is2xxSuccessful())
logger.info("Deleted with status " +
response.getStatusCode());
}
Complete Example
We are going to build two spring boot application. One application is exposing REST API and another application make http call to the former application.
Create Spring Boot application 1(expose REST APIs)
Final Project directory:
Complete pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>user-management-demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>user-management-demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
Create Entity - User.java
Create User Entity class
package com.knf.dev.demo.entity;
import jakarta.persistence.*;
@Entity
@Table(name = "_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
Create Repository - UserRepository.java
Create UserRepository class
package com.knf.dev.demo.repository;
import com.knf.dev.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
public interface UserRepository extends JpaRepository<User, Long> {
}
Create ErrorMessage.java
package com.knf.dev.demo.exception;
public class ErrorMessage {
private int status;
private String error;
private String description;
public ErrorMessage() {
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ErrorMessage(int status, String error, String description) {
this.status = status;
this.error = error;
this.description = description;
}
}
Create ResourceNotFoundException.java
package com.knf.dev.demo.exception;
public class ResourceNotFoundException extends RuntimeException {
private static final long serialVersionUID = 1L;
public ResourceNotFoundException(String msg) {
super(msg);
}
}
Create GlobalExceptionHandler.java
Create a global exception handler using ControllerAdvice annotation and ExceptionHandler annotation.
package com.knf.dev.demo.exception;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.context.request.WebRequest;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(ResourceNotFoundException.class)
public ResponseEntity<ErrorMessage> resourceNotFoundException(
ResourceNotFoundException ex, WebRequest request) {
ErrorMessage message = new ErrorMessage(
HttpStatus.NOT_FOUND.value(),
ex.getMessage(),
request.getDescription(false));
return new ResponseEntity<>(message, HttpStatus.NOT_FOUND);
}
}
Create UserController.java
package com.knf.dev.demo.controller;
import com.knf.dev.demo.entity.User;
import com.knf.dev.demo.exception.ResourceNotFoundException;
import com.knf.dev.demo.repository.UserRepository;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/v1/users")
public class UserController {
private final UserRepository userRepository;
public UserController(UserRepository userRepository) {
this.userRepository = userRepository;
}
// Fetch all users
@GetMapping
public ResponseEntity<List<User>> getAllUsers() {
return new ResponseEntity<>(userRepository.findAll(), HttpStatus.OK);
}
// create user
@PostMapping
public ResponseEntity<User> createUser(@RequestBody User user) {
return new ResponseEntity<>(userRepository.save(user), HttpStatus.CREATED);
}
// get user by id
@GetMapping("/{id}")
public ResponseEntity<User> getUserById(@PathVariable Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException
("Not found User with id = " + id));
return new ResponseEntity<>(user, HttpStatus.OK);
}
// update user
@PutMapping("/{id}")
public ResponseEntity<User> updateUser(@PathVariable Long id,
@RequestBody User userDetails) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException
("Not found User with id = " + id));
user.setEmail(userDetails.getEmail());
user.setName(userDetails.getName());
user.setAge(userDetails.getAge());
return new ResponseEntity<>(userRepository.save(user), HttpStatus.OK);
}
// delete user
@DeleteMapping("/{id}")
public ResponseEntity<HttpStatus> deleteUser
(@PathVariable Long id) {
User user = userRepository.findById(id)
.orElseThrow(() -> new ResourceNotFoundException
("Not found User with id = " + id));
return new ResponseEntity<>(HttpStatus.NO_CONTENT);
}
}
Main Application
package com.knf.dev.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class UserManagementDemoApplication {
public static void main(String[] args) {
SpringApplication.run(UserManagementDemoApplication.class, args);
}
}
Creating spring boot application 2 - RestClient
Final Project directory:
Complete pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.2.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.knf.dev.demo</groupId>
<artifactId>spring-restclient-app</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>spring-restclient-app</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
application.properties
user.base.url = http://localhost:8080/api/v1/users
spring.main.web-application-type=none
To use Spring Boot without a web server add spring.main.web-application-type=none property.
Create RestClient
package com.knf.dev.demo.config;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestClient;
@Configuration
public class RestClientConfig {
@Value("${user.base.url}")
String baseUrl;
@Bean
RestClient restClient() {
return RestClient.create(baseUrl);
}
}
Create Model - User
Create a user class.
package com.knf.dev.demo.model;
public class User {
private Long id;
private String name;
private String email;
private Integer age;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", email='" + email + '\'' +
", age=" + age +
'}';
}
}
Create ErrorMessage.java
package com.knf.dev.demo.response;
public class ErrorMessage {
private int status;
private String error;
private String description;
public ErrorMessage() {
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getError() {
return error;
}
public void setError(String error) {
this.error = error;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public ErrorMessage(int status, String error, String description) {
this.status = status;
this.error = error;
this.description = description;
}
@Override
public String toString() {
return "ErrorMessage{" +
"status=" + status +
", error='" + error + '\'' +
", description='" + description + '\'' +
'}';
}
}
Create UserService.java
package com.knf.dev.demo.service;
import com.knf.dev.demo.model.User;
import java.util.List;
public interface UserService {
User createUser(User user);
User updateUser(User user, Long id);
User findById(Long id);
User findByIdWithExchangeMethod(Long id);
List<User> getAllUsers();
List<User> getAllUsersAsResponseEntity();
void deleteUser(Long id);
}
Create UserServiceImpl.java
package com.knf.dev.demo.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.knf.dev.demo.model.User;
import com.knf.dev.demo.response.ErrorMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatusCode;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClient;
import java.util.List;
import java.util.Map;
@Service
public class UserServiceImpl implements UserService{
Logger logger = LoggerFactory.getLogger(UserServiceImpl.class);
private final RestClient restClient;
public UserServiceImpl(RestClient restClient) {
this.restClient = restClient;
}
@Override
public User createUser(User user) {
ResponseEntity<User> responseEntity = restClient.post()
.accept(MediaType.APPLICATION_JSON)
.body(user)
.retrieve()
.toEntity(User.class);
logger.info("User: " + responseEntity.getBody());
if (responseEntity.getStatusCode().is2xxSuccessful()) {
logger.info("Created: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
@Override
public User updateUser(User user, Long id) {
ResponseEntity<User> responseEntity = restClient.put()
.uri("/{id}",id)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON)
.body(user)
.retrieve()
.toEntity(User.class);
logger.info("User: " + responseEntity.getBody());
if (responseEntity.getStatusCode().is2xxSuccessful()) {
logger.info("Updated: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
@Override
public User findById(Long id) {
User user = restClient.get()
.uri("/{id}",id)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError,
(req, res) -> {
logger.error("Failed to get User: " + res.getStatusText());
logger.error("Failed to get User:" + res.getStatusCode());
}
)
.onStatus(HttpStatusCode::is5xxServerError,
(req, res) -> {
//TODO
})
.body(User.class);
logger.info("User: " + user);
return user;
}
@Override
public User findByIdWithExchangeMethod(Long id) {
User user = restClient.get()
.uri("/{id}", id)
.accept(MediaType.APPLICATION_JSON)
.exchange((request, response) -> {
if (response.getStatusCode().is4xxClientError()) {
logger.error("Failed to get User: " + response.getStatusText());
logger.error("Failed to get User:" + response.getStatusCode());
return null;
}
else {
ObjectMapper mapper = new ObjectMapper();
User _user = mapper.readValue(response.getBody(), User.class);
logger.error("User: " + _user);
return _user;
}
});
return user;
}
@Override
public List<User> getAllUsers() {
List<User> users = restClient.get()
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.body(List.class);
logger.info("List of users: " + users);
return users;
}
@Override
public List<User> getAllUsersAsResponseEntity() {
ResponseEntity<List> responseEntity = restClient.get()
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.toEntity(List.class);
logger.info("List of users: " + responseEntity.getBody());
if (responseEntity.getStatusCode().is2xxSuccessful()) {
logger.info("Fetched: " + responseEntity.getStatusCode());
}
return responseEntity.getBody();
}
@Override
public void deleteUser(Long id) {
ResponseEntity response = restClient.delete()
.uri("/{id}",id)
.accept(MediaType.APPLICATION_JSON)
.retrieve()
.onStatus(HttpStatusCode::is4xxClientError,
(req, res) -> {
logger.error("Couldn't delete:" + res.getStatusText());
logger.error("Couldn't delete:" + res.getStatusCode());
ObjectMapper mapper = new ObjectMapper();
ErrorMessage message = mapper.readValue(res.getBody(),
ErrorMessage.class);
logger.error("Couldn't delete:" + message);
}
)
.onStatus(HttpStatusCode::is5xxServerError,
(req, res) -> {
//TODO
}
)
.toBodilessEntity();
if (response.getStatusCode().is2xxSuccessful())
logger.info("Deleted with status " +
response.getStatusCode());
}
}
Main Application
package com.knf.dev.demo;
import com.knf.dev.demo.model.User;
import com.knf.dev.demo.service.UserService;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringRestclientAppApplication implements CommandLineRunner {
UserService userService;
public SpringRestclientAppApplication(UserService userService) {
this.userService = userService;
}
public static void main(String[] args) {
SpringApplication.run(SpringRestclientAppApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
//Create User1
User user = new User();
user.setAge(19);
user.setEmail("carl@knf.com");
user.setName("Carl");
userService.createUser(user);
//Create User2
User user2 = new User();
user2.setAge(45);
user2.setEmail("rick@knf.com");
user2.setName("Rick");
User userRick = userService.createUser(user2);
//Update User2
User _user2 = new User();
_user2.setAge(47);
_user2.setEmail("rick2@knf.com");
_user2.setName("Rick2");
userService.updateUser(_user2,userRick.getId());
//Find User2 by Id
userService.findById(userRick.getId());
//Find User2 by Id
userService.findByIdWithExchangeMethod(userRick.getId());
//Find by Id: Invalid id
userService.findById(123l);
//Find by Id: Invalid id
userService.findByIdWithExchangeMethod(123l);
//Get all users
userService.getAllUsers();
//Get all users with ResponseEntity
userService.getAllUsersAsResponseEntity();
//Delete user
userService.deleteUser(userRick.getId());
//Delete user: Invalid Id
userService.deleteUser(134l);
}
}
Verify our system is working as expected
Run the Spring Boot application - mvn spring-boot:run
OR
Run this Spring boot application from
- IntelliJ IDEA IDE by right click - Run 'Application.main()'
- Eclipse/STS - You can right click the project or the Application.java file and run as java application or Spring boot application.
Run the Spring Boot application - mvn spring-boot:run
OR
Run this Spring boot application from
- IntelliJ IDEA IDE by right click - Run 'Application.main()'
- Eclipse/STS - You can right click the project or the Application.java file and run as java application or Spring boot application.
Console Output of Spring Boot application 2
2023-12-20T09:43:34.918+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=1, name='Carl', email='carl@knf.com', age=19}
2023-12-20T09:43:34.922+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Created: 201 CREATED
2023-12-20T09:43:35.168+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick', email='rick@knf.com', age=45}
2023-12-20T09:43:35.169+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Created: 201 CREATED
2023-12-20T09:43:35.584+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick2', email='rick2@knf.com', age=47}
2023-12-20T09:43:35.585+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Updated: 200 OK
2023-12-20T09:43:35.604+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick2', email='rick2@knf.com', age=47}
2023-12-20T09:43:35.624+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick2', email='rick2@knf.com', age=47}
2023-12-20T09:43:35.659+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User: Not Found
2023-12-20T09:43:35.659+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User:404 NOT_FOUND
2023-12-20T09:43:35.661+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=null, name='null', email='null', age=null}
2023-12-20T09:43:35.682+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User: Not Found
2023-12-20T09:43:35.683+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User:404 NOT_FOUND
2023-12-20T09:43:36.115+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : List of users: [{id=1, name=Carl, email=carl@knf.com, age=19}, {id=2, name=Rick2, email=rick2@knf.com, age=47}]
2023-12-20T09:43:36.132+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : List of users: [{id=1, name=Carl, email=carl@knf.com, age=19}, {id=2, name=Rick2, email=rick2@knf.com, age=47}]
2023-12-20T09:43:36.133+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Fetched: 200 OK
2023-12-20T09:43:36.169+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Deleted with status 204 NO_CONTENT
2023-12-20T09:43:36.186+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Couldn't delete:Not Found
2023-12-20T09:43:36.186+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Couldn't delete:404 NOT_FOUND
2023-12-20T09:43:36.204+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Couldn't delete:ErrorMessage{status=404, error='Not found User with id = 134', description='uri=/api/v1/users/134'}
2023-12-20T09:43:34.918+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=1, name='Carl', email='carl@knf.com', age=19}
2023-12-20T09:43:34.922+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Created: 201 CREATED
2023-12-20T09:43:35.168+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick', email='rick@knf.com', age=45}
2023-12-20T09:43:35.169+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Created: 201 CREATED
2023-12-20T09:43:35.584+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick2', email='rick2@knf.com', age=47}
2023-12-20T09:43:35.585+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Updated: 200 OK
2023-12-20T09:43:35.604+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick2', email='rick2@knf.com', age=47}
2023-12-20T09:43:35.624+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=2, name='Rick2', email='rick2@knf.com', age=47}
2023-12-20T09:43:35.659+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User: Not Found
2023-12-20T09:43:35.659+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User:404 NOT_FOUND
2023-12-20T09:43:35.661+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : User: User{id=null, name='null', email='null', age=null}
2023-12-20T09:43:35.682+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User: Not Found
2023-12-20T09:43:35.683+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Failed to get User:404 NOT_FOUND
2023-12-20T09:43:36.115+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : List of users: [{id=1, name=Carl, email=carl@knf.com, age=19}, {id=2, name=Rick2, email=rick2@knf.com, age=47}]
2023-12-20T09:43:36.132+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : List of users: [{id=1, name=Carl, email=carl@knf.com, age=19}, {id=2, name=Rick2, email=rick2@knf.com, age=47}]
2023-12-20T09:43:36.133+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Fetched: 200 OK
2023-12-20T09:43:36.169+05:30 INFO 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Deleted with status 204 NO_CONTENT
2023-12-20T09:43:36.186+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Couldn't delete:Not Found
2023-12-20T09:43:36.186+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Couldn't delete:404 NOT_FOUND
2023-12-20T09:43:36.204+05:30 ERROR 5300 --- [ main] c.knf.dev.demo.service.UserServiceImpl : Couldn't delete:ErrorMessage{status=404, error='Not found User with id = 134', description='uri=/api/v1/users/134'}