Development/Spring Boot3 (Kotlin)

[Kotlin][SpringBoot3] Kopring 서버 기본 실습 12 - api response 데이터 형식을 다수의 data class 활용한 여러 entity 결합해 소스코드 수정해보기

Tradgineer 2023. 9. 19. 08:16

 

1. 이전 포스팅

 

https://growingsaja.tistory.com/979

 

[Kotlin][SpringBoot3] Kopring 서버 실습 11 - api의 기능 변경 실습

1. 이전 포스팅 https://growingsaja.tistory.com/976 2. user 관련 api 수정 예정 < 1차 > - login 시도시, 해당 fromIp가 존재하지 않으면 회원가입 처리 진행 - login 시도시, 해당 fromIp가 존재하면 최근접속시간 업

growingsaja.tistory.com

 

 

 

 

 

2. 목표

 

api server 정보를 return하는 api를 H2 database와 함께 연계해 구현

단, api server 정보 return하는 api의 결과 데이터 예시는 다음과 같게 할 것

{
  "status": {
    "code": "000",
    "message": "success",
    "timestamp": "2023-09-18T15:15:38.028637"
  },
  "result": {
    "id": 1,
    "recentVersion": "0.0.1",
    "stableVersion": "0.0.1",
    "isDisable_startApp": false,
    "text_startApp": "111",
    "lastUpdateBackendAt": "2023-09-18T15:15:14.273695"
  }
}

 

 

 

 

 

3. 프로젝트 새로 만들기

 

실습 12까지 구현한 기능과 별개의 base 안에 별도의 controller, entity, repository, service를 만들어줍니다.

 

기능 단위로 해당 구조를 만들어주는 것이 추후 유지보수시 편리합니다.

 

 

 

 

 

4. entity에 data class 먼저 만들기

 

base/controllers

base/entities

base/repositories

base/services

 

 

 

 

 

5. Entities

 

 - api response의 status에 들어가는 데이터 형식 선언

// vim StatusOfResponse.kt

package com.dev.kopring00.base.entities

import java.time.LocalDateTime

data class StatusOfResponse(
    var code: String? = null,
    var message: String? = null,
    val timestamp: LocalDateTime = LocalDateTime.now()
)

 

 - api response의 result에 들어가는 데이터 형식 선언

// vim entities/ApiServer.kt

package com.dev.kopring00.base.entities

import jakarta.persistence.Entity
import jakarta.persistence.GeneratedValue
import jakarta.persistence.GenerationType
import jakarta.persistence.Id
import java.time.LocalDateTime

@Entity
data class ApiServer(
    // @Id 어노테이션은 이 필드가 엔터티의 기본 키(primary key)임을 나타냅니다.
    @Id
    // @GeneratedValue 어노테이션은 기본 키의 생성 전략을 나타내며, IDENTITY 전략은 데이터베이스가 자동으로 기본 키 값을 생성하도록 지시합니다.
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    val id: Int = 0,

    /* ===== 앱 업데이트 안내 ===== */
    val recentVersion: String? = null,    // 가장 최근 배포된 버전 이상    >>> 조치 없음
    // recentVersion 미만 & stableVersion 이상                         >>> 앱 업데이트 권고
    val stableVersion: String? = null, // 최소 버전 = 해당 버전 미만      >>> 앱 업데이트 강제

    /* ===== 앱 실행 차단 (ex. 긴급 점검) ===== */
    val isServiceOutage: Boolean? = null, // 장애 상황인 경우 true로 바꿔, 모든 앱 실행자의 진입을 차단
    val text_serviceOutage: String? = null, // 장애 상황인 경우 노출되는 안내 문구

    // api server 최근 재가동 일시
    val lastRestartAt: LocalDateTime? = null
)

 

 - api response 데이터 형식 선언

// vim ApiServerResponse.kt

package com.dev.kopring00.base.entities

data class ApiServerResponse(
    var status: StatusOfResponse,
    var result: ApiServer
)

 

 - 서버 가동시 H2 database에 기본으로 입력될 초기 기본 데이터 설정

// vim ApiServerInitialData.kt

package com.dev.kopring00.base.entities

import com.dev.kopring00.base.repositories.SystemInfoRepository
import jakarta.annotation.PostConstruct
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Component
import java.time.LocalDateTime

@Component
class ApiServerInitialData @Autowired constructor(private val systemInfoRepository: SystemInfoRepository) {
    @PostConstruct
    fun loadData() {
        // 최신 정보로 1개 데이터만 List로 기재
        val initialApiServerData = listOf(
            ApiServer(1, "0.0.1", "0.0.1", false, "서비스 점검 중입니다.", LocalDateTime.now()),
        )
        systemInfoRepository.saveAll(initialApiServerData)
    }
}

 

 

 

 

 

6. repositories

 

 - api server 정보 가져오는 용도의 repository

// vim ApiServerRepository.kt

package com.dev.kopring00.base.repositories

import com.dev.kopring00.base.entities.ApiServer
import org.springframework.data.jpa.repository.JpaRepository

interface ApiServerRepository: JpaRepository<ApiServer, Int> {}

 

 

 

 

 

7. services

 

 - repository로 api server 데이터 가져온 것 : result

 - entity에서 status of response 데이터 가져온 것 : status

    => 위 둘을 조합해 api server response 제작 : response

// vim ApiServerService.kt

package com.dev.kopring00.base.services

import com.dev.kopring00.base.entities.ApiServerResponse
import com.dev.kopring00.base.entities.StatusOfResponse
import com.dev.kopring00.base.repositories.ApiServerRepository
import org.springframework.stereotype.Service

@Service
class ApiServerService(private val apiServerRepository: ApiServerRepository) {
    fun getRecentSystemInfo(): ApiServerResponse {
        return ApiServerResponse(
            StatusOfResponse("000", "success"),
            apiServerRepository.findAll().first()
        )
    }
}

 

 

 

 

 

8. api controller 구현

 

// vim ApiServerController.kt

package com.dev.kopring00.base.controllers

import com.dev.kopring00.base.entities.ApiServerResponse
import com.dev.kopring00.base.services.ApiServerService
import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController

@RestController
@RequestMapping("/api/v1/system/info")
class ApiServerController(private val apiServerService: ApiServerService) {
    @GetMapping("/recent")
    fun getRecentSystemInfo(): ApiServerResponse {
        return apiServerService.getRecentSystemInfo()
    }
}