1. 이전 포스팅

 

https://growingsaja.tistory.com/991

 

[Kotlin][SpringBoot3] Kopring 서버 기본 실습 13 - 새로운 프로젝트 파서 깔끔한 조회, 저장, 수정 기능 ap

1. 이전 포스팅 https://growingsaja.tistory.com/984 [Kotlin][SpringBoot3] Kopring 서버 기본 실습 12 - api response 데이터 형식을 다수의 data class 활용한 여러 e 1. 이전 포스팅 https://growingsaja.tistory.com/979 [Kotlin][Spring

growingsaja.tistory.com

 

 

 

 

 

2. 목표

 

실시간 환율 정보 및 가상자산 정보를 수집해 저장하고, 데이터를 가공해 제공하는 api가 구현된 백엔드 서버 개발

 - 개발하는 백엔드 시스템 기본 정보 저장용 DB로 H2 사용

 - 서비스 데이터는 모두 MongoDB에 저장 및 관리

    ㄴ 본 포스팅에서는 MongoDB 내용을 다루지 않지만, 이후 포스팅에서 개발되는 기능들에서는 MongoDB를 활용합니다.

 

 

 

 

 

3. 프로젝트 새로 만들기 in IntelliJ

 

Name : Kotlin

Language : Gradle - Kotlin

Name : kopring00

Group : com.dev

Developer Tools -> Sptring Boot DevTools

Web -> Spring Web

SQL -> Spring Data JPA

SQL -> H2 Database

NoSQL -> Spring Data MongoDB

 

 

 

 

 

4. 프로젝트 구조 세팅 - 폴더

 

 - base : 추후 계속 사용하거나, 기본적인 api 기능 관련 구현

controllers

entities

repositories

services

 

 - external : 구현할 새로운 기능들 중 하나로, 필자는 외부 api에 call해서 정보 수집 및 가공하는 기능을 모으는 용도로 사용 예정

      ㄴ fiat : 법정 화폐 정보 수집 및 가공 기능 구현 예정

      ㄴ fiat 말고 다른 패키지를 만들며 추가 기능 탑재 예정 (현재는 없음)

 

 

 

 

 

5. swagger 적용

 

https://growingsaja.tistory.com/962

 

[Kotlin][SpringBoot3] Kopring 서버 실습 03 - Swagger 적용하기 (using springdoc)

1. 이전 포스팅 https://growingsaja.tistory.com/954 [Kotlin][SpringBoot3] Kopring 서버 실습 02 - 간단한 api 구현 및 외부 api의 결과값을 가져와 return하는 api 1. 참고하면 좋은 이전 포스팅 https://growingsaja.tistory.com/

growingsaja.tistory.com

// vim build.gradle.kts

// ...

dependencies {
    // ...

    // swagger
    implementation("org.springdoc:springdoc-openapi-starter-webmvc-ui:2.2.0")
}

// ...

 

http://localhost:8080/swagger-ui/index.html#/

 

 

 

 

 

6. api 공통 response 형태 사전 설계

 

// vim StatusOfResponse.kt

package com.dev.kopring00.base.entities

import java.time.LocalDateTime

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

 - 참조

https://growingsaja.tistory.com/984

 

[Kotlin][SpringBoot3] Kopring 서버 기본 실습 12 - api response 데이터 형식을 다수의 data class 활용한 여러 e

1. 이전 포스팅 https://growingsaja.tistory.com/979 [Kotlin][SpringBoot3] Kopring 서버 실습 11 - api의 기능 변경 실습 1. 이전 포스팅 https://growingsaja.tistory.com/976 2. user 관련 api 수정 예정 < 1차 > - login 시도시, 해당

growingsaja.tistory.com

 

 

 

 

 

7. H2 적용

 

backend 정보 관리를 위한 H2 Database 설정

 

https://growingsaja.tistory.com/964

 

[Kotlin][SpringBoot3] Kopring 서버 실습 04 - local DB 연동하기 (H2 DB, JPA 사용)

1. 이전 포스팅 https://growingsaja.tistory.com/962 [Kotlin][SpringBoot3] Kopring 서버 실습 03 - Swagger 적용하기 (using springdoc) 1. 이전 포스팅 https://growingsaja.tistory.com/954 [Kotlin][SpringBoot3] Kopring 서버 실습 02 - 간단

growingsaja.tistory.com

# vim /main/resources/application.properties

spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:mem:default-setting

 

http://localhost/h2-console

 - 기본 데이터셋

// 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,

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

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

    // api server 최근 재가동 일시
    val lastRestartAt: LocalDateTime = LocalDateTime.now()
)
// vim ApiServerInitialData.kt

package com.dev.kopring00.base.entities

import com.dev.kopring00.base.repositories.ApiServerRepository
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 apiServerRepository: ApiServerRepository) {
    @PostConstruct
    fun loadData() {
        // 최신 정보로 1개 데이터만 List로 기재
        val initialApiServerData = listOf(
            ApiServer(
                1, 
                "0.0.1", 
                "0.0.1", 
                false, 
                 "서비스 점검 중입니다."
            ),
        )
        apiServerRepository.saveAll(initialApiServerData)
    }
}

 

 

 

 

 

8. H2 데이터 활용 기능 구현

 

// vim ApiServerResponse.kt

package com.dev.kopring00.base.entities

data class ApiServerResponse(
    var status: StatusOfResponse,
    var result: ApiServer?
)
// 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> {}
// vim ApiServerService.kt

package com.dev.kopring00.base.services

import com.dev.kopring00.base.entities.ApiServer
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 {
        val recentSystemInfoAll = apiServerRepository.findAll()
        return if (recentSystemInfoAll.isNotEmpty()) {
            ApiServerResponse(
                StatusOfResponse("100", "success"),
                recentSystemInfoAll.first()
            )
        } else {
            ApiServerResponse(
                StatusOfResponse("204", "no data"),
                null
            )
        }
    }
}

 

 - 데이터가 없으면 result에 null 데이터가 들어간채로 return합니다.

// 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()
    }
}

 

 

 

 

 

9. MongoDB 적용하는데에 도움이 필요하다면 복습하러 가기

 

 - repository JpaRepository와 DB 2개 동시에 연동하는 부분 필요시 참조

 

https://growingsaja.tistory.com/972

 

[Kotlin][SpringBoot3] Kopring 서버 실습 06 - CrudRepository에서 JpaRepository로 변경 적용 + H2 DB와 MongoDB 동시

1. 이전 포스팅 https://growingsaja.tistory.com/967 [Kotlin][SpringBoot3] Kopring 서버 실습 05 - MongoDB 연동하기 (MongoDB 7 사용) 1. 이전 포스팅 https://growingsaja.tistory.com/964 2. mongodb 설치 필자의 경우 mac에서 진행하

growingsaja.tistory.com

 

 

 

 

 

+ Recent posts