Spring boot

[JPA] λΈ”λ‘œκ·Έ ν”„λ‘œμ νŠΈ λ§Œλ“€κΈ° - 1

미둜910 2024. 10. 2. 12:04
πŸ’‘
1. REST API에 λŒ€ν•œ κ°œλ…κ³Ό μ£Όμš” νŠΉμ§•μΌ μ„€λͺ…ν•  수 μžˆλ‹€.
2. application-dev.yml νŒŒμΌμ„ ν™œμ„±ν™”ν•΄μ„œ μ‚¬μš©ν•  수 μžˆλ‹€.

 

REST APIλž€

REST API(Representational State Transfer Application Programming Interface)λŠ” λ„€νŠΈμ›Œν¬ μƒμ—μ„œ μžμ›μ„ μš”μ²­ν•˜κ³  μ‘°μž‘ν•˜κΈ° μœ„ν•œ μ•„ν‚€ν…μ²˜ μŠ€νƒ€μΌμž…λ‹ˆλ‹€. REST APIλŠ” 주둜 HTTP ν”„λ‘œν† μ½œμ„ 기반으둜 ν•˜λ©°, ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„ κ°„μ˜ 톡신을 λ‹¨μˆœν•˜κ³  효율적으둜 μˆ˜ν–‰ν•  수 μžˆλ„λ‘ν•˜λŠ” ν‘œμ€€ν™” 된 μ•½μ†μž…λ‹ˆλ‹€.

 

REST API의 μ£Όμš” νŠΉμ§•

  • λ¬΄μƒνƒœμ„± (Statelessness): 각 μš”μ²­μ€ 독립적이며, μ„œλ²„λŠ” ν΄λΌμ΄μ–ΈνŠΈμ˜ μƒνƒœλ₯Ό μ €μž₯ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€. λͺ¨λ“  μš”μ²­μ—λŠ” ν•„μš”ν•œ λͺ¨λ“  정보가 ν¬ν•¨λ˜μ–΄ μžˆμ–΄μ•Ό ν•©λ‹ˆλ‹€.
  • ν΄λΌμ΄μ–ΈνŠΈ-μ„œλ²„ ꡬ쑰: ν΄λΌμ΄μ–ΈνŠΈμ™€ μ„œλ²„λŠ” μ„œλ‘œ λ…λ¦½μ μœΌλ‘œ λ™μž‘ν•˜λ©°, ν΄λΌμ΄μ–ΈνŠΈλŠ” μš”μ²­μ„ 보내고 μ„œλ²„λŠ” 그에 λŒ€ν•œ 응닡을 μ œκ³΅ν•©λ‹ˆλ‹€.
  • μžμ› 기반: APIλŠ” μžμ›(데이터)에 λŒ€ν•΄ λ™μž‘ν•˜λ©°, 각 μžμ›μ€ κ³ μœ ν•œ URIλ₯Ό 톡해 μ‹λ³„λ©λ‹ˆλ‹€. μžμ›μ€ 예λ₯Ό λ“€μ–΄ μ‚¬μš©μž, 파일, κ²Œμ‹œλ¬Ό 등이 될 수 μžˆμŠ΅λ‹ˆλ‹€.
  • HTTP λ©”μ„œλ“œ μ‚¬μš©:
    • GET: μžμ›μ„ μ‘°νšŒν•  λ•Œ μ‚¬μš©
    • POST: μƒˆλ‘œμš΄ μžμ›μ„ 생성할 λ•Œ μ‚¬μš©
    • PUT: κΈ°μ‘΄ μžμ›μ„ μ—…λ°μ΄νŠΈν•  λ•Œ μ‚¬μš©
    • DELETE: μžμ›μ„ μ‚­μ œν•  λ•Œ μ‚¬μš©
  • ν‘œν˜„μ˜ λ‹€μ–‘μ„±: JSON, XML λ“± λ‹€μ–‘ν•œ ν˜•μ‹μœΌλ‘œ 데이터λ₯Ό 주고받을 수 있으며, λŒ€λΆ€λΆ„μ˜ REST APIλŠ” 가볍고 직관적인 JSON 포맷을 μ„ ν˜Έν•©λ‹ˆλ‹€.

 

ν”„λ‘œμ νŠΈ 생성

 

build.gradle
plugins {
	id 'java'
	id 'org.springframework.boot' version '3.2.10'
	id 'io.spring.dependency-management' version '1.1.6'
}

group = 'com.example'
version = '0.0.1-SNAPSHOT'

java {
	toolchain {
		languageVersion = JavaLanguageVersion.of(21)
	}
}

configurations {
	compileOnly {
		extendsFrom annotationProcessor
	}
}

repositories {
	mavenCentral()
}

dependencies {
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	developmentOnly 'org.springframework.boot:spring-boot-devtools'
	runtimeOnly 'com.h2database:h2'
	//runtimeOnly 'com.mysql:mysql-connector-j'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}


tasks.named('test') {
	useJUnitPlatform()
}

 

μ˜μ‘΄μ„± λ²”μœ„ μ§€μ •(Dependency Scope) 확인

implementation: μ• ν”Œλ¦¬μΌ€μ΄μ…˜ 컴파일 및 λŸ°νƒ€μž„ μ‹œ ν•„μš”ν•œ μ˜μ‘΄μ„±.

compileOnly: 컴파일 μ‹œμ—λ§Œ ν•„μš”ν•œ μ˜μ‘΄μ„±, λŸ°νƒ€μž„ μ‹œ ν¬ν•¨λ˜μ§€ μ•ŠμŒ.

developmentOnly: 개발 μ€‘μ—λ§Œ ν•„μš”ν•œ μ˜μ‘΄μ„±, ν”„λ‘œλ•μ…˜ λΉŒλ“œμ—λŠ” ν¬ν•¨λ˜μ§€ μ•ŠμŒ.

runtimeOnly: λŸ°νƒ€μž„ μ‹œμ—λ§Œ ν•„μš”ν•œ μ˜μ‘΄μ„±, 컴파일 μ‹œμ—λŠ” ν•„μš”ν•˜μ§€ μ•ŠμŒ.

annotationProcessor: 컴파일 μ‹œμ— μ–΄λ…Έν…Œμ΄μ…˜ ν”„λ‘œμ„Έμ‹±μ— ν•„μš”ν•œ μ˜μ‘΄μ„±. (컴파일 κ³Όμ • 쀑에 νŠΉμ • μ–΄λ…Έν…Œμ΄μ…˜μ„ ν•΄μ„ν•˜κ³ , 그에 따라 좔가적인 μ½”λ“œλ₯Ό μƒμ„±ν•˜κ±°λ‚˜ κ²€μ¦ν•˜λŠ” μž‘μ—…)

testImplementation: ν…ŒμŠ€νŠΈ μ½”λ“œμ˜ 컴파일 및 μ‹€ν–‰ μ‹œ ν•„μš”ν•œ μ˜μ‘΄μ„±.

testRuntimeOnly: ν…ŒμŠ€νŠΈ μ‹€ν–‰ μ‹œμ—λ§Œ ν•„μš”ν•œ μ˜μ‘΄μ„±, 컴파일 μ‹œμ—λŠ” ν•„μš”ν•˜μ§€ μ•ŠμŒ.

 

λΉŒλ“œ μ‹œμŠ€ν…œμ΄λž€?

λΉŒλ“œ μ‹œμŠ€ν…œμ€ μ†Œν”„νŠΈμ›¨μ–΄ κ°œλ°œμ—μ„œ μ†ŒμŠ€ μ½”λ“œλ₯Ό μ‹€ν–‰ κ°€λŠ₯ν•œ ν”„λ‘œκ·Έλž¨μœΌλ‘œ λ³€ν™˜ν•˜λŠ” 일련의 과정을 μžλ™ν™”ν•˜λŠ” 도ꡬ λ˜λŠ” ν”„λ‘œμ„ΈμŠ€λ₯Ό λ§ν•©λ‹ˆλ‹€.

  1. 컴파일:
    • κ°œλ°œμžκ°€ μž‘μ„±ν•œ μ†ŒμŠ€ μ½”λ“œλ₯Ό 기계가 이해할 수 μžˆλŠ” λ°”μ΄νŠΈ μ½”λ“œ λ˜λŠ” κΈ°κ³„μ–΄λ‘œ λ³€ν™˜ν•˜λŠ” κ³Όμ •μž…λ‹ˆλ‹€. ( μžλ°” μ†ŒμŠ€ 파일(.java)을 μ»΄νŒŒμΌν•˜μ—¬ .class 파일둜 λ³€ν™˜)
  2. μ˜μ‘΄μ„± 관리:
    • ν”„λ‘œμ νŠΈμ—μ„œ μ‚¬μš©ν•˜λŠ” μ™ΈλΆ€ 라이브러리(예: JUnit, Spring λ“±)λ₯Ό μžλ™μœΌλ‘œ λ‹€μš΄λ‘œλ“œν•˜κ³ , μ μ ˆν•œ 버전을 μœ μ§€ν•˜λ©°, 이λ₯Ό ν”„λ‘œμ νŠΈμ— ν¬ν•¨μ‹œν‚΅λ‹ˆλ‹€. (Gradle, Maven 같은 도ꡬ μ‚¬μš©)
  3. νŒ¨ν‚€μ§•:
    • 컴파일된 μ†ŒμŠ€ μ½”λ“œμ™€ ν•¨κ»˜ ν•„μš”ν•œ 파일(λ¦¬μ†ŒμŠ€, μ„€μ • 파일 λ“±)을 ν•˜λ‚˜λ‘œ νŒ¨ν‚€μ§•ν•˜μ—¬ 배포 κ°€λŠ₯ν•œ ν˜•νƒœλ‘œ λ§Œλ“­λ‹ˆλ‹€. (μžλ°” ν”„λ‘œμ νŠΈμ˜ 경우 JAR(Java ARchive) νŒŒμΌμ„ 생성)
  4. ν…ŒμŠ€νŠΈ μžλ™ν™”:
    • μ½”λ“œκ°€ μž‘μ„±λ˜λ©΄, λΉŒλ“œ μ‹œμŠ€ν…œμ€ μžλ™μœΌλ‘œ ν…ŒμŠ€νŠΈλ₯Ό μ‹€ν–‰ν•˜μ—¬ μ½”λ“œκ°€ μ˜¬λ°”λ₯΄κ²Œ λ™μž‘ν•˜λŠ”μ§€ ν™•μΈν•©λ‹ˆλ‹€. (Gradleμ΄λ‚˜ Mavenμ—μ„œ JUnit ν…ŒμŠ€νŠΈλ₯Ό μžλ™μœΌλ‘œ μ‹€ν–‰)
  5. 배포:
    • λΉŒλ“œκ°€ μ™„λ£Œλ˜λ©΄, ν”„λ‘œκ·Έλž¨μ„ μ„œλ²„λ‚˜ 배포 ν™˜κ²½μ— μžλ™μœΌλ‘œ λ°°ν¬ν•˜λŠ” κΈ°λŠ₯을 지원할 수 μžˆμŠ΅λ‹ˆλ‹€.(CI/CD 도ꡬ와 μ—°κ³„ν•˜μ—¬ μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ„ ν΄λΌμš°λ“œ ν™˜κ²½μ— 배포)

Gradleκ³Ό Maven은 λŒ€ν‘œμ μΈ λΉŒλ“œ μ‹œμŠ€ν…œ λ„κ΅¬λ‘œ, 각각 μ˜μ‘΄μ„± 관리, 컴파일, ν…ŒμŠ€νŠΈ, νŒ¨ν‚€μ§•, 배포 λ“±μ˜ μž‘μ—…μ„ μžλ™ν™”ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

application.yml
spring:
  application:
    name: class_blog_jpa_v1

  server:
    port: 8080
  
  datasource:
    url: jdbc:mysql://localhost:3306/jpa_demo?useSSL=false&serverTimeZone=Asia/Seoul
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root 
    password: asd123

  profiles:
    active: dev  # prod  # κΈ°λ³Έ ν™œμ„±ν™” ν”„λ‘œνŒŒμΌμ„ dev둜 μ„€μ •
application-dev.yml 파일 μˆ˜μ •
server:
  servlet:
    encoding:
      charset: utf-8         # μš”μ²­ 및 응닡에 UTF-8 인코딩을 μ‚¬μš©ν•˜μ—¬ ν•œκΈ€ 및 νŠΉμˆ˜λ¬Έμžκ°€ κΉ¨μ§€μ§€ μ•Šλ„λ‘ μ„€μ •
      force: true            # κ°•μ œλ‘œ UTF-8 인코딩을 적용, ν΄λΌμ΄μ–ΈνŠΈκ°€ λ‹€λ₯Έ 인코딩을 μš”μ²­ν•˜λ”λΌλ„ λ¬΄μ‹œν•˜κ³  UTF-8을 μ‚¬μš©
  port: 8080                 # μ„œλ²„κ°€ 8080 ν¬νŠΈμ—μ„œ μ‹€ν–‰λ˜λ„λ‘ μ„€μ •

spring:
  mustache:
    servlet:
      expose-session-attributes: true  # Mustache ν…œν”Œλ¦Ώμ—μ„œ μ„Έμ…˜ 속성에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν—ˆμš©
      expose-request-attributes: true  # Mustache ν…œν”Œλ¦Ώμ—μ„œ μš”μ²­ 속성에 μ ‘κ·Όν•  수 μžˆλ„λ‘ ν—ˆμš©
  datasource:
    driver-class-name: org.h2.Driver    # λ°μ΄ν„°λ² μ΄μŠ€ λ“œλΌμ΄λ²„λ‘œ H2 DBλ₯Ό μ‚¬μš©
    url: jdbc:h2:mem:test;MODE=MySQL    # H2 인메λͺ¨λ¦¬ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό MySQL ν˜Έν™˜ λͺ¨λ“œλ‘œ μ‚¬μš© (ν…ŒμŠ€νŠΈμš©)
    username: sa                        # λ°μ΄ν„°λ² μ΄μŠ€ μ—°κ²° μ‹œ κΈ°λ³Έ μ‚¬μš©μž 이름
    password:                           # λ°μ΄ν„°λ² μ΄μŠ€ κΈ°λ³Έ λΉ„λ°€λ²ˆν˜Έ (λΉ„μ–΄ 있음)
  h2:
    console:
      enabled: true   # H2 λ°μ΄ν„°λ² μ΄μŠ€ μ½˜μ†”μ„ ν™œμ„±ν™”ν•˜μ—¬ λΈŒλΌμš°μ €μ—μ„œ λ°μ΄ν„°λ² μ΄μŠ€λ₯Ό 관리할 수 μžˆλ„λ‘ 함
  #sql:
    #init:
      #data-locations:
        #- classpath:db/data.sql  # μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ΄ˆκΈ°ν™” μ‹œ μ‹€ν–‰ν•  데이터 μ‚½μž… SQL 파일의 경둜 (data.sql)
  jpa:
    hibernate:
      ddl-auto: create            # μ• ν”Œλ¦¬μΌ€μ΄μ…˜μ΄ μ‹œμž‘λ  λ•Œ λ°μ΄ν„°λ² μ΄μŠ€ ν…Œμ΄λΈ”μ„ μžλ™μœΌλ‘œ 생성
    show-sql: true                # Hibernateκ°€ μ‹€ν–‰ν•˜λŠ” SQL 쿼리λ₯Ό μ½˜μ†”μ— 좜λ ₯
    properties:
      hibernate:
        format_sql: true          # 좜λ ₯λ˜λŠ” SQL 쿼리λ₯Ό ν¬λ§·νŒ…ν•˜μ—¬ 읽기 μ‰½κ²Œ 좜λ ₯
    defer-datasource-initialization: true  # λ°μ΄ν„°λ² μ΄μŠ€ μ΄ˆκΈ°ν™”κ°€ μ§€μ—°λ˜λ„λ‘ μ„€μ •ν•˜μ—¬ JPA μ„€μ • 후에 데이터 μ΄ˆκΈ°ν™”

  output:
    ansi:
      enabled: always  # μ½˜μ†” 좜λ ₯ μ‹œ ANSI 색상을 항상 μ‚¬μš©ν•˜λ„λ‘ μ„€μ • (색상을 톡해 둜그λ₯Ό 더 μ‰½κ²Œ ꡬ뢄 κ°€λŠ₯)

logging:
  level:
    '[com.example.class_blog_jpa_v1]': DEBUG  # νŠΉμ • νŒ¨ν‚€μ§€(com.tenco.blog_jpa_step1) μˆ˜μ€€μ—μ„œ DEBUG 레벨둜 λ‘œκΉ…μ„ μ„€μ •