빈티지 테라피

Kotlin과 Spring Boot로 시작하는 마이크로서비스 개발 본문

코드 테라피

Kotlin과 Spring Boot로 시작하는 마이크로서비스 개발

밍키스튜디오 2023. 9. 30. 15:53
반응형

목차


마이크로서비스란?

마이크로서비스는 큰 어플리케이션을 여러 개의 작은 서비스 단위로 분리한 아키텍처 패턴입니다. 각 서비스는 독립적으로 배포하고 확장할 수 있으며, 특정 비즈니스 로직에 초점을 맞춥니다.

장점:
* 각 서비스가 독립적으로 운영되므로 전체 시스템에 미치는 영향을 최소화합니다.
* 다양한 기술 스택과 프레임워크를 선택하여 사용할 수 있습니다.
* 확장성과 유지보수성을 향상시킵니다.

단점:
* 데이터 일관성 관리와 네트워크 오버헤드 등의 복잡한 문제를 다루어야 합니다.

Kotlin 소개

Kotlin은 JetBrains에서 개발한 정적 타입의 프로그래밍 언어입니다. Java와 100% 호환되며, null 안전성, 람다 표현식 및 고차 함수 지원 등 현대적인 기능을 제공합니다.

// Hello World in Kotlin
fun main() {
    println("Hello, World!")
}

Spring Boot 소개

Spring Boot는 자바 플랫폼을 위한 오픈 소르 프레임워크인 Spring Framework를 쉽게 사용할 수 있도록 도와주는 도구입니다.

// Hello World in Spring Boot
import org.springframework.boot.*;
import org.springframework.boot.autoconfigure.*;
import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

    @RequestMapping("/")
    String home() {
        return "Hello, World!";
    }

    public static void main(String[] args) {
        SpringApplication.run(Example.class, args);
    }

}

환경 설정

  1. JDK 설치: Kotlin과 Spring Boot를 사용하려면 Java Development Kit(JDK)가 필요합니다.
  2. IntelliJ IDEA 설치: JetBrains에서 제작한 이 IDE는 Kotlin과 Spring Boot 개발에 최적화되어 있습니다.
  3. Spring Initializr로 프로젝트 생성: 웹 기반 도구인 Spring Initializr를 사용하여 새 프로젝트를 생성합니다.
* Group: com.example
* Artifact: myservice
* Name: myservice
* Description: My first microservice with Kotlin and Spring Boot
* Package Name: com.example.myservice
* Packaging: Jar 
* Java Version: 11 (or newer)

첫번째 마이크로서비스 만들기

첫 번째 마이크로서비스는 간단한 "Hello, World!" 메시지를 반환하는 REST API입니다.

import org.springframework.boot.autoconfigure.SpringBootApplication
import org.springframework.boot.runApplication

@SpringBootApplication // (1)
class MyserviceApplication

fun main(args: Array<String>) {
    runApplication<MyserviceApplication>(*args) // (2)
}

위 코드에서 (1)은 이 클래스가 스프링 부트 애플리케이션의 주 진입점임을 나타내고, (2)는 애플리케이션을 시작하는 함수입니다.

REST API 만들기

Spring MVC 패턴을 사용하여 HTTP 요청을 처리하는 컨트롤러를 작성합니다.

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController // (1)
class HelloController {

    @GetMapping("/") // (2)
    fun hello(): String {
        return "Hello, World!"
    }
}

위 코드에서 (1)은 이 클래스가 REST 컨트롤러임을 나타내며, HTTP 요청을 처리하고 응답 본문에 직접 데이터를 작성합니다.
(2)는 HTTP GET 요청에 대해 "/" 경로에 매핑되며 해당 메소드가 호출됩니다.

데이터베이스 연동하기

Spring Data JPA와 H2 데이터베이스를 사용하여 간단한 CRUD(Create-Read-Update-Delete) 기능을 구현해봅시다.

  1. 도메인 모델 생성
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity // This tells Hibernate to make a table out of this class.
data class User(
    @Id @GeneratedValue(strategy = GenerationType.AUTO)
    val id: Long = 0,
    val name: String = "",
)

위 코드는 User 엔티티를 정의합니다. 이 클래스는 데이터베이스 테이블에 매핑됩니다.

  1. 리포지터리 인터페이스 생성
import org.springframework.data.repository.CrudRepository

interface UserRepository : CrudRepository<User, Long> // This will be AUTO IMPLEMENTED by Spring into a Bean called userRepository.

UserRepository 인터페이스는 Spring Data JPA가 제공하는 CrudRepository를 확장하며, 이를 통해 기본적인 CRUD 연산을 수행할 수 있습니다.

  1. 서비스 클래스 생성
import org.springframework.stereotype.Service

@Service
class UserService(private val userRepository: UserRepository) {

    fun createUser(user: User): User {
        return userRepository.save(user)
    }

    fun getAllUsers(): List<User> {
        return userRepository.findAll().toList()
    }

    fun getUserById(id: Long): User? {
        return userRepository.findById(id).orElse(null)
    }

    fun updateUser(id: Long, user: User): User? {
        return userRepository.findById(id).map { existingUser ->
            val updatedUser: User = existingUser.copy(name = user.name)
            userRepository.save(updatedUser)
        }.orElse(null)
     }

     fun deleteUser(id: Long) {
         if(userRepository.existsById(id)) {  
             userRepository.deleteById(id) 
         } 
     }
}
  1. 컨트롤러 클래스 생성
import org.springframework.web.bind.annotation.*

@RestController
@RequestMapping("/users")
class UserController(private val userService: UserService) {

   @PostMapping("/")
   fun createUser(@RequestBody user: User): ResponseEntity<User> {
       return ResponseEntity.ok(userService.createUser(user))
   }

   @GetMapping("/")
   fun getAllUsers(): ResponseEntity<List<User>>{
       return ResponseEntity.ok(userService.getAllUsers())
   }

   @GetMapping("/{id}")
   fun getUserById(@PathVariable("id") id :Long): ResponseEntity<User>{
       val user = userService.getUserById(id)
       return if (user != null){
           ResponseEntity.ok(user);
       } else{
           ResponseEntity.notFound().build();
       }

   }

  @PutMapping("/{id}")
  fun updateUser(@PathVariable("id") id :Long, @RequestBody newUser :User ):ResponseEntity<User>{
      val updatedUser=userService.updateUser( id,newUser)
      return if(updatedUser != null){
          ResponseEntity.ok(updatedUser)
      } else{
          ResponseEntity.notFound().build()
      }
  }

  @DeleteMapping("/{id}")
  fun deleteUser(@PathVariable("id") id :Long):ResponseEntity<Void>{
      userService.deleteUser(id)
      return ResponseEntity.noContent().build();
  }
}

이제 Kotlin과 Spring Boot를 사용하여 마이크로서비스를 개발하는 방법에 대해 간략하게 알아보았습니다. 이러한 기본적인 구조를 바탕으로 더 복잡한 서비스를 개발하고 확장할 수 있습니다.

반응형