Clean coding practices ensure that your Spring Boot applications are maintainable, readable, and scalable. This guide provides essential tips and code examples to help you write cleaner and more efficient code in both Java and Kotlin.
Written by
Şuayb Şimşek
Backend-focused fullstack developer sharing practical notes on Spring Boot, security, microservices, and cloud-native architecture.
The following example gives practical context for Example: Entity with Lombok and can be applied directly.
JAVAUser.java
package com.example.cleanproject.entity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.AllArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
}
Benefits:
@Data generates getters, setters, equals, hashCode, and toString methods.
@NoArgsConstructor and @AllArgsConstructor create constructors.
🛠️ Step 3: Write Concise and Readable Code in Kotlin
Kotlin offers modern features that naturally lead to cleaner code:
Example: Entity in Kotlin
The following example gives practical context for Example: Entity in Kotlin and can be applied directly.
KOTLINUser.kt
package com.example.cleanproject.entity
import jakarta.persistence.*
@Entity
data class User(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long = 0,
var name: String,
var email: String
)
Advantages of Kotlin:
data class automatically generates toString, equals, and hashCode methods.
Use dependency injection to decouple components and improve testability.
Example: Service Layer with DI
The following example gives practical context for Example: Service Layer with DI and can be applied directly.
🛠️ Step 5: Use DTOs for Data Transfer
Data Transfer Objects (DTOs) separate your domain and API layers, promoting better encapsulation.
Example: DTO for User
The following example gives practical context for Example: DTO for User and can be applied directly.
Controller Layer
Implement a controller to handle HTTP requests and interact with the service layer.
▶️ Running the Application
Run the application using the following command:
BASH
./mvnw spring-boot:run
Test endpoints using a tool like Postman or cURL.
🧪 Testing the API
You can test the API using the following cURL command:
Fetch all users:
BASH
curl -X GET http://localhost:8080/api/users
🏁 Conclusion
You now have a practical Clean Coding Practices in Spring Boot implementation with a clear, production-friendly Spring Boot structure. As a next step, adapt configuration and tests to your own domain, then validate behavior under realistic traffic and failure scenarios.
JAVAUserService.java
package com.example.cleanproject.service;
import com.example.cleanproject.entity.User;
import com.example.cleanproject.repository.UserRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@RequiredArgsConstructor
public class UserService {
private final UserRepository userRepository;
public List<User> getAllUsers() {
return userRepository.findAll();
}
}
KOTLINUserService.kt
package com.example.cleanproject.service
import com.example.cleanproject.entity.User
import com.example.cleanproject.repository.UserRepository
import org.springframework.stereotype.Service
@Service
class UserService(
private val userRepository: UserRepository
) {
fun getAllUsers(): List<User> = userRepository.findAll()
}
JAVAUserDTO.java
package com.example.cleanproject.dto;
import lombok.Data;
@Data
public class UserDTO {
private String name;
private String email;
}
KOTLINUserDTO.kt
package com.example.cleanproject.dto
data class UserDTO(
val name: String,
val email: String
)
JAVAUserController.java
package com.example.cleanproject.controller;
import com.example.cleanproject.dto.UserDTO;
import com.example.cleanproject.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@GetMapping
public List<UserDTO> getAllUsers() {
return userService.getAllUsers();
}
}
KOTLINUserController.kt
package com.example.cleanproject.controller
import com.example.cleanproject.dto.UserDTO
import com.example.cleanproject.service.UserService
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/api/users")
class UserController(
private val userService: UserService
) {
@GetMapping
fun getAllUsers(): List<UserDTO> = userService.getAllUsers()
}