Cache는 본래 CPU 내부의 작은 영역으로 정말 빈번히 접근하게 되는 데이터를 저장해두는 임시기억 장치이다. 기본적으로 영속성을 위해 파일시스템(디스크)에 저장하고, 빠른 활용을 위해 메모리(RAM)에 저장한다면, 정말 많이 사용되는 휘발성 데이터가 캐시에 저장된다. 

 

이러한 캐시의 목적과 방식을 적용해 빈번하게 접근하게 되는 데이터베이스의 데이터를 Redis 등의 인메모리 데이터베이스에 저장함으로서 데이터를 조회하는데 걸리는 시간과 자원을 감소시키는 기술을 캐싱이라고 한다.

 

웹 브라우저에서는 자주 바뀌지 않는 이미지 등을 브라우저 캐시에 저장해 페이지 로드를 줄이는 것도 캐싱의 일종이다. 이는 RESTful 설계 원칙 중에서 응답이 캐싱이 가능한지 명시해야 한다는 제약사항으로도 나타난다.

 

'TIL' 카테고리의 다른 글

RabbitMQ 와 Kafka  (0) 2025.03.07
DB인덱싱  (0) 2025.03.06
Redis  (0) 2025.03.04
Spring Security의 @AuthenticationPrincipal 이해하기  (0) 2025.02.25
restdocs  (0) 2025.02.20

Redis : In-memory DB

 

RDS DB는 영속성을 제공하는데 목적을 두고있다. 이는 데이터가 사라지지 않게 하기 위해 파일시스템(SSD, HDD 등)에 저장한다는 의미이다. 컴퓨터가 저장되어도 데이터가 사라지지 않지만 기본적으로 데이터를 읽고 쓰는데 오래걸린다.

 

하지만 Redsi는 메모리, 즉 RAM에 데이터를 저장하기 때문에 복작한 입출력 과정이 필요하지 않다. RDS보다 빠르지만 언제든 사라질 수 있는 데이터를 다룬다. 특정 게시글의 조회수와 같이 빠르게 업데이트 되는 데이터, 또는 사용자 세션, 장바구니와 같은 시간이 지나면 삭제되는 데이터 등을 저장하기 위해 가장 많이 사용되어온 DB이다.

 

Redis는 NoSQL DB이다.

일반적인 RDS DB는 SQL을 사용한다.

SELECT * FROM users;

 

Redis를 비롯한 NoSQL DB는 (일반적으로) SQL을 사용하지 않는다.

SET greeting "Hello, Redis!"
GET greeting

 

NoSQL은 현재는 Not only SQL을 의미한다. 

기술이 발전함에 따라 데이터가 증가하고, 비정형데이터가 많아지고, 확장성과 유연성이 떨어져서 NoSQL이 생겨난것이다.

NoSQL DB의 종류 몇가지

  • Key-Value: 가장 단순한 형태의 데이터베이스로, Key에 Value를 저장하는 형태입니다. JSON, Python의 Dictionary, Java의 Map의 형태로 데이터를 관리한다고 생각할 수 있습니다.
  • Document: 객체를 표현하는 Document라는 단위로 데이터를 저장하는 형태입니다. Key - Value에서 발전했다고 볼 수 있으며, JSON, XML 등 복잡한 데이터를 저장하고 관리합니다.
  • Column-Family: 각 Row의 Column이 고정되어있지 않고, 필요한 데이터 Column을 이름, 데이터, Timestamp와 함께 저장하는 형태의 데이터베이스 입니다.

 

'TIL' 카테고리의 다른 글

DB인덱싱  (0) 2025.03.06
Cache  (0) 2025.03.05
Spring Security의 @AuthenticationPrincipal 이해하기  (0) 2025.02.25
restdocs  (0) 2025.02.20
n+1을 해결하는 여러가지 방식의 장단점  (0) 2025.02.19

@AuthenticationPrincipal 어노테이션은 Spring Security에서 인증된 사용자 정보를 손쉽게 접근할 수 있도록 도와주는 기능입니다. Spring Security를 사용하여 인증 및 인가를 처리할 때, 인증된 사용자의 정보를 서비스 계층이나 컨트롤러에서 쉽게 가져오고자 할 때 유용합니다. 이 어노테이션은 보통 Principal 객체를 주입하는 방식과 유사하지만, 더 직관적이고 간편하게 사용할 수 있도록 도와줍니다.

1. @AuthenticationPrincipal이란?

@AuthenticationPrincipal은 Spring Security의 Authentication 객체에서 현재 인증된 사용자의 정보를 직접 가져올 수 있게 해주는 어노테이션입니다. Authentication 객체는 사용자가 로그인 시 저장된 인증 정보를 담고 있으며, 이를 통해 로그인한 사용자의 이름, 권한, 역할 등을 가져올 수 있습니다.

2. 사용 예시

2.1. 기본적인 사용

@AuthenticationPrincipal을 사용하면 인증된 사용자 객체를 쉽게 주입받을 수 있습니다. 보통 사용자 정보를 담고 있는 클래스는 UserDetails 인터페이스를 구현합니다. 예를 들어, 사용자 정보를 CustomUserDetails 클래스에 담고 있다면 다음과 같이 사용할 수 있습니다.

@Controller
public class MyController {

    @GetMapping("/profile")
    public String getUserProfile(@AuthenticationPrincipal CustomUserDetails userDetails) {
        // 인증된 사용자 정보 사용
        System.out.println("Authenticated user: " + userDetails.getUsername());
        return "profile";
    }
}

2.2. UserDetailsService와 함께 사용

@AuthenticationPrincipal을 사용하려면 보통 UserDetailsService를 사용하여 사용자 정보를 로드하는 방식과 함께 사용됩니다. CustomUserDetailsService 클래스를 구현하여 사용자 정보를 로드하고, Spring Security에서 제공하는 AuthenticationManager를 통해 인증을 처리하는 방식입니다.

@Service
public class CustomUserDetailsService implements UserDetailsService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        User user = userRepository.findByUsername(username)
            .orElseThrow(() -> new UsernameNotFoundException("User not found"));
        return new CustomUserDetails(user);
    }
}

3. 장점

  • 간결성: @AuthenticationPrincipal을 사용하면 Authentication 객체를 직접 다룰 필요 없이, 인증된 사용자 정보를 쉽게 주입받을 수 있습니다.
  • 유연성: UserDetails를 구현한 클래스에 따라 사용자 정보를 다르게 설정하고 사용할 수 있습니다.
  • 보안 강화: 인증된 사용자 정보만을 주입받기 때문에 보안 측면에서도 유리합니다.

4. 주의할 점

  • @AuthenticationPrincipal은 주로 Principal 객체가 아닌 인증된 사용자의 상세 정보를 담고 있는 객체를 주입받기 위해 사용됩니다. 따라서 CustomUserDetails와 같은 클래스를 UserDetails 인터페이스로 구현해 사용해야 합니다.
  • 인증되지 않은 사용자가 접근할 수 있는 경로에서는 @AuthenticationPrincipal을 사용할 수 없으므로, 적절한 예외 처리가 필요합니다.

5. 결론

Spring Security에서 @AuthenticationPrincipal 어노테이션은 인증된 사용자 정보를 쉽게 가져올 수 있는 매우 유용한 도구입니다. 이를 사용하면 코드가 간결해지고, Authentication 객체를 직접 다루지 않고도 인증된 사용자의 상세 정보를 손쉽게 다룰 수 있습니다. 특히 사용자 인증 및 관리가 중요한 애플리케이션에서 이 어노테이션을 활용하면 보다 깔끔하고 안전한 코드 작성이 가능합니다.

'TIL' 카테고리의 다른 글

Cache  (0) 2025.03.05
Redis  (0) 2025.03.04
restdocs  (0) 2025.02.20
n+1을 해결하는 여러가지 방식의 장단점  (0) 2025.02.19
data.sql을 활용한 초기 데이터 설정  (0) 2025.02.14

1. Spring RestDocs란?

Spring RestDocs는 API 문서를 자동으로 생성해주는 도구로, 테스트 코드에서 API 요청과 응답을 기반으로 문서를 생성할 수 있습니다. 이는 API 문서를 코드와 동기화된 상태로 유지할 수 있게 도와주며, Swagger와 같은 다른 문서화 도구보다 신뢰성이 높습니다.

2. Spring RestDocs의 장점

  • 테스트 기반 문서화: API 테스트 코드와 함께 동작하므로 실제 요청/응답을 기반으로 문서가 생성됩니다.
  • 정확한 문서 유지: 코드와 문서가 따로 관리되지 않기 때문에 변경 사항이 자동으로 반영됩니다.
  • Markdown 및 Asciidoc 지원: Asciidoc을 활용하여 다양한 포맷으로 문서를 생성할 수 있습니다.
  • Swagger 대비 장점: 코드와 문서가 분리되지 않으며, API 변경 사항을 놓칠 가능성이 적습니다.

3. Spring RestDocs와 다른 문서화 도구 비교

문서화 도구장점단점

Spring RestDocs 실제 API 응답을 기반으로 문서 자동 생성, 코드와 문서 동기화 보장 UI 기반 문서 제공 없음, 초기 설정이 다소 복잡
Swagger UI 기반 API 문서 제공, 인터랙티브한 API 테스트 가능 수동으로 작성해야 하며 코드와 문서가 불일치할 가능성 있음
Postman API 테스트와 문서화를 함께 수행 가능, 공유 기능이 뛰어남 코드와 문서가 동기화되지 않음, 버전 관리 어려움
Redoc Swagger 기반의 미려한 UI 제공, 문서 유지보수 용이 Swagger를 기반으로 하기 때문에 Swagger의 단점과 동일

'TIL' 카테고리의 다른 글

Redis  (0) 2025.03.04
Spring Security의 @AuthenticationPrincipal 이해하기  (0) 2025.02.25
n+1을 해결하는 여러가지 방식의 장단점  (0) 2025.02.19
data.sql을 활용한 초기 데이터 설정  (0) 2025.02.14
Github Project & Issue  (0) 2025.02.13

1. @Query와 leftjoin (JPQL)
엔티티들을 한번의 SQL쿼리로 조회
장점 : 간단함
단점 : JOIN FETCH 많이 사용하면 쿼리 복잡도 증가. 연관된 엔티티가 많으면 쿼리 실행 시간 증가.

2. EntityGraph
EntityGraph는 JPA에서 제공하는 기능,
특정 연관 관계를미리 로딩하도록 지정 가능
장점 : JPA표준기능이라 여러 쿼리에서 사용가능
재사용성 높음
단점 : 동적 쿼리나 매우 복잡한쿼리에는 부적함

3. @OneToMany 에서 FetchType.LAZY가 아닌 FetchType.EAGER
비추천
장점 : 간단함
단점 : 성능 저하

4. Batch Fetching
연관된 엔티티들을 한 번에 묶어서 가져오는 방식
장점 : 연관된 엔티티들을 한 번에 묶어서 조회할 수 있어 성능 최적화 가능
BatchSize를 통해 배치 크기 조절 가능
단점 : 메모리 사용량 증가

5. QueryDSL
동적 쿼리를 작성할때 JOIN을 사용해 연관된 엔티티들을 한 번에 가져오는 방식
장점 : 동적쿼리작성가능, 코드의 가독성이 높음. 실무에서 많이 사용함.
단점 : 어려움

6. 서브쿼리
장점 : 메인쿼리 단순하게 유지가능
단점 : 복잡한 sql

7. NativeQuery
SQL을 직접작성하여 원하는 데이터를 직접 가져오기.
장점 : sql을 직접작성하므로 최적화 작업을 자유롭게 가능
JPA, JPQL보다 SQL에 대한 더 높은 제어권을 가짐
단점 : JPA와 통합 어려움
DB의존적임. DB에 종속적이므로 DB를 변경할 경우 쿼리를 수정해야함
clear, flush를 자주 사용해야하고 잘 사용해야함

8. EntityGraph와 JOIN FETCH의 결합
장점 : 동적 조정가능
단점 : 복잡한 쿼리, 메모리 사용량 증가

'TIL' 카테고리의 다른 글

Spring Security의 @AuthenticationPrincipal 이해하기  (0) 2025.02.25
restdocs  (0) 2025.02.20
data.sql을 활용한 초기 데이터 설정  (0) 2025.02.14
Github Project & Issue  (0) 2025.02.13
MSA는 필수적일까?  (0) 2025.02.11

data.sql 은 Spring Boot 를 실행할 때 자동으로 실행되는 SQL 파일이다. 주로 애플리케이션을 실행할 때 데이터베이스에 기본 데이터를 삽입하거나 테스트 데이터를 설정하는데 사용된다. 이 파일은 src/main/resources 디렉토리에 위치한다.

 

data.sql 의 장점

 

 

  • 자동 데이터삽입 : data.sql을 활용하면 애플리케이션 실행 시 data.sql 이 자동으로 실행해 별도로 데이터를 삽입할 필요 없이 자동으로 데이터베이스 초기화가 이루어진다. 이를 통해 개발 초기 상태를 쉽게 만들 수 있다.
  • 테스트 데이터 관리 : 개발 및 테스트 환경에서 반복적으로 사용할 데이터베이스 초기 데이터를 관리할 수 있다. 실행마다 동일한 데이터를 쉽게 삽입하기 때문에 데이터베이스의 일관성을 유지할 수 있다.
  • 간편한 데이터 삽입 : SQL문을 직접 작성할 수 있기 때문에 직관적이고 빠르다.

비슷한 테스트 데이터 삽입 방법으로 TestDataRunner가 있다. TestDataRunner 의 차이점은 다음과 같다.

구분 data.sql TestDataRunner
실행 시점 애플리케이션 시작 시 자동 실행 테스트 실행 전, 후에 수동으로 실행
실행 방식 SQL 쿼리 직접 작성 Java 코드로 데이터 삽입
데이터베이스 독립성 데이터베이스에 의존적인 SQL 문 작성 Spring 환경에 맞춰 동적으로 데이터 삽입 가능

 

data.sql 을 사용하기위해서 application.properties 를 설정해 주어야 한다.

spring.datasource.initialization-mode=always

spring.datasource.initialization-mode: 데이터베이스 초기화 모드를 설정합니다. always로 설정하면 애플리케이션 시작 시 data.sql을 실행하게 됩니다.

 

이는 스키마가 이미 존재할 때 사용해야 한다. 스키마 도 새로 설정해야한다면 스키마 설정과 데이터도 추가해 줘야한다. 나는 스키마는 있었으므로 데이터만 추가했었다.

 

'TIL' 카테고리의 다른 글

Spring Security의 @AuthenticationPrincipal 이해하기  (0) 2025.02.25
restdocs  (0) 2025.02.20
n+1을 해결하는 여러가지 방식의 장단점  (0) 2025.02.19
Github Project & Issue  (0) 2025.02.13
MSA는 필수적일까?  (0) 2025.02.11

개발 프로젝트를 관리하는것은 복잡하고 어려운 일이다. 이를 좀 더 쉽고 효율적으로 관리하기위해 많은 프로젝트 관리 도구가 있다. 대표적인 예로 Jira, Github Project가 있다. 그 중에서 Github Project에 관해 작성해보겠다.

 

Github Project의 장점 : 

  • Github Project의 가장 큰 장점 중 하나는 코드 저장소와 프로젝트 관리 도구가 하나의 플랫폼에 통합되어 있다는 것이다. 코드를 저장하고 관리할때 Github를 통해 관리하니 한번에 관리할 수 있어 좋다. 이는 개발자들이 코드 작업과 프로젝트 진행 상황을 동시에 관리할 수 있어 작업 흐름이 매우 자연스럽다.

 

  • Github Project는 유연한 칸반 보드 시스템을 제공한다. 팀원들은 자신들의 워크 플로우에 맞게 칸반 보드를 구성해서 팀의 특정 요구사항에 맞는 사용자 정의 열을 추가할 수 있다.

위 사진처럼 Todo, In Progress, Done 보드 3개로 간단하게 구성해서 사용할 수 있다. 생성된 Issue를 Close하면 자동으로 Done 으로 이동하게된다.

 

또한, Issue를 생성할 때 템플릿을 설정해 좀더 가독성 좋고 간단하게 이슈를 생성하고 PR할 수있다. 

 

'TIL' 카테고리의 다른 글

Spring Security의 @AuthenticationPrincipal 이해하기  (0) 2025.02.25
restdocs  (0) 2025.02.20
n+1을 해결하는 여러가지 방식의 장단점  (0) 2025.02.19
data.sql을 활용한 초기 데이터 설정  (0) 2025.02.14
MSA는 필수적일까?  (0) 2025.02.11

이번에 새로 진행할 프로젝트는 '음식 주문 관리 플랫폼' 개발이다.

우리팀은 백엔드 개발팀으로서 프로젝트에 참여했다.(라고 상상하며 시작하자)

먼저 기획자가 알려준 개발 요구사항 명세서를 확인해보자. 

더보기
  • 개발 요구사항 명세서 - 배달 및 포장 음식 주문 관리 플랫폼
  • 프로젝트 개요
    • 주제: 배달 및 포장 음식 주문 관리 플랫폼 개발
    • 목표: 광화문 근처에서 운영될 음식점들의 배달 및 포장 주문 관리, 결제, 그리고 주문 내역 관리 기능을 제공하는 플랫폼 개발
  • 운영 지역
    • 지역: 초기에는 광화문 근처로 한정하여 운영하며, 향후 확장을 고려한 지역 분류 시스템 설계 필요
    • 향후 확장성: 지역별 필터링, 지역정보 수정 및 추가 등이 가능 하도록 고려
  • 음식점 분류
    • 카테고리: 다음과 같은 음식점 카테고리로 분류
      • 한식
      • 중식
      • 분식
      • 치킨
      • 피자
    • 향후 확장성: 음식점 카테고리를 추가하거나 수정할 수 있도록 유연한 데이터 구조 설계 필요
  • 결제 시스템
    • 결제 방식: 카드 결제만 가능
    • PG사 연동: PG사와의 결제 연동은 외주 개발로 진행하며, 결제 관련 내역만 플랫폼의 데이터베이스에 저장
    • 결제 테이블: 결제 내역을 저장하기 위한 전용 테이블 설계
  • 주문 관리
    • 주문 취소: 주문 생성 후 5분 이내에만 취소 가능하도록 제한
    • 주문 유형: 온라인 주문과 대면 주문(가게에서 직접 주문) 모두 지원
    • 대면 주문 처리: 가게 사장님이 직접 대면 주문을 접수
  • 데이터 보존 및 삭제 처리
    • 데이터 보존: 모든 데이터는 완전 삭제되지 않고 숨김 처리로 관리
    • 상품 숨김: 개별 상품도 숨김 처리 가능하도록 구현(숨김과 삭제는 다른 필드에서 동작해야함)
    • 데이터 감사 로그: 모든 정보에 생성일, 생성 아이디, 수정일, 수정 아이디, 삭제일, 삭제 아이디를 포함
  • 접근 권한 관리
    • 고객: 자신의 주문 내역만 조회 가능
    • 가게 주인: 자신의 가게 주문 내역, 가게 정보, 주문 처리 및 메뉴 수정 가능
    • 관리자: 모든 가게 및 주문에 대한 전체 권한 보유
  • 배송지 정보
    • 필수 입력 사항: 주소지, 요청 사항
    • ‘주문’ 과 ‘배달’ 에 모두 관련된 정보 입니다!
  • AI API 연동
    • 상품 설명 자동 생성: AI API를 연동하여 가게 사장님이 상품 설명을 쉽게 작성할 수 있도록 지원
    • AI 요청 기록: AI API 요청 질문과 대답은 모두 데이터베이스에 저장
  • 주문 확인 방식(프론트 앤드 개발자 담당)
    • 프론트엔드 폴링: 프론트엔드에서 주기적으로 주문 확인을 위해 주문 API를 호출하는 폴링 방식 사용
  • 개발 및 인프라 확장
    • 개발 속도: 빠른 개발을 통해 프로토타입을 신속히 확인
    • 인프라 확장: 시스템 설계는 간결하게 유지하되, 향후 인프라 확장을 고려
  • 기술 스택
    • 프론트엔드: React.js 또는 Vue.js (권장) 및 REST API 통신
      • ⇒ 프론트 앤드 개발자가 개발 할 것!
    • 백엔드: Spring Boot 3.x
    • 데이터베이스: PostgreSQL
    • 빌드 툴: Gradle
    • 버전 관리: Git을 이용한 버전 관리 (GitHub, GitLab, Bitbucket 등)
    • API 문서: 제시된 작성 툴이나 양식에 맞추어 작성
      • 프론트 엔드 개발자가 API문서만 보고도 개발 할 수 있게 작성할 것!
  • 프로젝트 구조
    • Monolithic Application
      • 해당 프로젝트는 기본적으로 모놀리틱으로 개발하며, 다음 프로젝트부터 MSA로 개발 예정
    • Layered Architecture: Controller, Service, Repository 계층으로 구성된 클린 아키텍처 권장
    • Entity 및 DTO: 각 기능별로 Entity와 DTO(Data Transfer Object)를 분리하여 관리
    • API 설계: RESTful API 원칙에 따라 설계
    • Exception Handling: 글로벌 예외 처리 (ExceptionHandler 사용)
  • 데이터베이스 설계
    • 테이블 명명 규칙: 모든 테이블에 p_ 접두사 사용
    • UUID 사용: 모든 주요 엔티티의 식별자는 UUID를 사용 (유저는 예외)
    • Audit 필드: 모든 테이블에 created_at, created_by, updated_at, updated_by, deleted_at, deleted_by 필드를 추가하여 데이터 감사 로그 기록
    • ERD 설계: 엔티티 간의 관계를 명확히 하는 ERD(Entity-Relationship Diagram) 작성
  • 보안
    • JWT 인증: Spring Security와 JWT(Json Web Token)를 이용한 인증 및 권한 관리
    • 권한 확인 : CUSTOMER 이상의 권한은 요청마다 저장되어 있는 권한 값과 동일한지 체크필요
    • 비밀번호 암호화: BCrypt 해시 알고리즘을 사용한 비밀번호 암호화
    • 데이터 유효성 검사: 서버 측 데이터 유효성 검사를 위해 Spring Validator 사용
  • 테스트
    • 테스트: Spring Boot Test를 사용한 테스트
    • Spring Boot Test 을 반드시 사용할 필요는 없으나, 적절한 테스트 방법을 선정하여 진행
  • AI API 연동
    • AI API 호출: AI 서비스(API)와의 연동을 위한 REST API 호출 로직 구현
    • AI 응답 데이터 저장: AI API 호출 시 요청 및 응답 데이터를 DB에 저장
  • 요구사항을 확인해보고 필수기능을 먼저 만들기위해 대략적인 API 명세서, 테이블 명세서, ERD 명세서, 인프라 설계서를 만들어봐야 할 것 같다. 요구사항이 어느정도 나와있어서 ERD 설계를 먼저 해보기로 했다. 

ERD 설계서

'

그리고 위의 ERD 설계서를 보고 API 명세서를 작성해보았다.

API 명세는 최대한 RESTful API 원칙에 따라 작성해 프론트 엔드 개발자가 API 문서만 보고도 개발 할 수 있게 작성을 해보았다. 일부 Search 기능에는 페이지네이션기능을 추가해주었다. 각 엔티티 별로 필요한만한 API들을 만들었다.

 

API 명세서

더보기

 

 

 

그리고 다음은 ERD 명세서와 API 명세서를 바탕으로 테이블 명세서를 작성해 주었다.

테이블 명세서는 요구사항에 맞게 각 테이블명의 시작은 p_table로 시작한다. 그리고 유저 ID는 최소 4자 ~ 10자. 다른 테이블의 id는 UUID로 정의했다. 모든 테이블은 데이터 감사 로그를 기록해야하므로 created_at, created_by, updated_at, updated_by, deleted_at, deleted_by 필드를 추가했다.

 

테이블 명세서

마지막으로 인프라 설계서를 작성해주었다. 최대한 간단하게 표현하기 위해 프론트, Docker 등을 제외하고 백엔드 관점에서의 시스템 아키텍처만 작성해주었다.

 

인프라 설계서

+ Recent posts