Certainly! Here is an example of an API for managing accounts using Kotlin, Spring Boot, the clean architecture principles, and DTOs (data transfer objects) to decouple the service and controller layers from the entity layer:
First, let's define the Account entity and the AccountRepository interface:
import javax.persistence.*
@Entity
@Table(name = "accounts")
data class Account(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
val id: Long,
val name: String
)
import org.springframework.data.jpa.repository.JpaRepository
interface AccountRepository : JpaRepository<Account, Long>
Next, let's define the AccountDto class to use as a DTO:
data class AccountDto(val id: Long, val name: String)
Now, let's define the AccountService interface:
interface AccountService {
fun getAccounts(): List<AccountDto>
fun createAccount(accountDto: AccountDto): AccountDto
fun updateAccount(id: Long, accountDto: AccountDto): AccountDto
fun deleteAccount(id: Long)
}
Now, let's implement the AccountService interface and the AccountController:
import org.springframework.stereotype.Service
@Service
class AccountServiceImpl(private val accountRepository: AccountRepository) : AccountService {
private fun toDto(account: Account) = AccountDto(account.id, account.name)
private fun toEntity(accountDto: AccountDto) = Account(accountDto.id, accountDto.name)
override fun getAccounts() = accountRepository.findAll().map { toDto(it) }
override fun createAccount(accountDto: AccountDto) = toDto(accountRepository.save(toEntity(accountDto)))
override fun updateAccount(id: Long, accountDto: AccountDto): AccountDto {
val existingAccount = accountRepository.findById(id).orElseThrow { NotFoundException() }
val updatedAccount = toEntity(accountDto).copy(id = existingAccount.id)
return toDto(accountRepository.save(updatedAccount))
}
override fun deleteAccount(id: Long) {
accountRepository.deleteById(id)
}
}
import org.springframework.web.bind.annotation.*
@RestController
@RequestMapping("/accounts")
class AccountController(private val accountService: AccountService) {
@GetMapping
fun getAccounts() = accountService.getAccounts()
@PostMapping
fun createAccount(@RequestBody accountDto: AccountDto): AccountDto {
return accountService.createAccount(accountDto)
}
@PutMapping("/{id}")
fun updateAccount(@PathVariable id: Long, @RequestBody accountDto: AccountDto): AccountDto {
return accountService.updateAccount(id, accountDto)
}
@