실무에서의 권장 방식

  • Create, Update는 분리하는 것이 일반적입니다.
    • Create는 대부분 필수 필드가 많고, 기본값 설정이나 추가적인 유효성 검사를 요구합니다.
    • Update는 부분 업데이트(Partial Update)를 지원해야 하는 경우가 많아, 선택적인 필드를 허용합니다.
  • Read와 Write를 분리하라 (CQRS 원칙에 따라):
    • Read용 DTO: 사용자에게 데이터를 반환할 때 최적화된 필드만 포함.
    • Write용 DTO (Create/Update): 요청 데이터를 받을 때 필요한 필드만 포함.

➡︎ Create, Update 요청 DTO 분리

  • CreateXxxDto: 생성 전용
  • UpdateXxxDto: 수정 전용

➡︎ Create, Update 응답 DTO 형식이 유사하다면 통일해도 됨

  • XxxReadResponseDto : 읽기 전용
  • XxxResponseDto : 생성/수정

 

프로젝트 할 때마다 궁금했는데, 최종 프로젝트를 앞두고 API 설계를 하다가 찾아봤다!

RESTful API의 본질과 설계 원칙

RESTful API의 핵심은 다음과 같은 6가지 원칙을 따르는 것입니다:

  1. 클라이언트-서버 구조: 클라이언트와 서버가 독립적으로 동작.
  2. 무상태성(Stateless): 각 요청은 독립적이며 서버는 클라이언트 상태를 저장하지 않음.
  3. 캐시 가능(Cacheable): 응답 데이터가 캐싱 가능.
  4. 계층화(Layered System): 클라이언트-서버 간 중간 계층 존재 가능.
  5. 통합된 인터페이스(Uniform Interface): 일관된 URI와 메서드 사용.
  6. 코드 온 디맨드(Optional): 서버에서 클라이언트로 실행 가능한 코드를 보낼 수 있음.
  • RESTful APIHTTP 메서드(GET, POST, PUT, DELETE 등)를 사용하여 리소스를 관리하는 스타일을 따릅니다.
  • CRUD 중심 설계는 데이터(리소스)의 생성(Create), 조회(Read), 갱신(Update), 삭제(Delete) 작업을 API로 제공하는 설계 방식입니다.
  • 따라서, CRUD 설계는 RESTful API의 한 형태일 뿐이며, RESTful API는 더 넓은 범위를 포괄합니다.

여태까지 RESTful API 가 CRUD 중심의 API 설계라고 생각하고 있었는데 아니었다...!

 

DDD와 이벤트 기반 설계도 RESTful한가?

DDD 중심 설계와 이벤트 기반 설계도 RESTful API의 기본 원칙을 지킬 수 있습니다:

  • 리소스 중심: 비즈니스 도메인 모델(포인트, 결제, 사용자 등)을 리소스로 정의.
  • HTTP 메서드: 리소스의 상태를 변경하거나 조회할 때 HTTP 메서드를 올바르게 사용.
  • 표현성: 리소스의 상태를 API 응답으로 표현.

예를 들어, 다음 API는 RESTful하면서도 CRUD 중심이 아닙니다:

  1. POST /points/earn: 포인트 적립(도메인 중심 설계).
  2. POST /events/payment-completed: 결제 완료 이벤트 처리(이벤트 기반 설계)
  • http와 https
    • 웹에서 데이터를 전송하는 주요 프로토콜입니다
    • HTTP (HyperText Transfer Protocol)
      • 보안: 데이터가 암호화되지 않고 평문으로 전송됩니다. 이는 네트워크를 통해 전송되는 데이터가 도청, 중간자 공격 등에 취약할 수 있음을 의미합니다.
      • 포트: 기본적으로 80번 포트를 사용합니다.
      • 속도: HTTPS에 비해 약간 빠를 수 있지만, 보안이 취약합니다.
      • 사용: 보안이 크게 중요하지 않은 웹사이트에서 주로 사용됩니다.
    • HTTPS (HyperText Transfer Protocol Secure)
      • 보안: SSL/TLS(보안 소켓 계층/전송 계층 보안) 프로토콜을 사용하여 데이터를 암호화합니다. 이는 데이터의 기밀성과 무결성을 보장하며, 사용자의 개인정보와 민감한 데이터를 보호합니다.
      • 포트: 기본적으로 443번 포트를 사용합니다.
      • 속도: 암호화/복호화 과정이 필요하기 때문에 약간 느릴 수 있습니다. 그러나 현대의 컴퓨팅 능력과 최적화된 SSL/TLS 구현 덕분에 차이가 거의 느껴지지 않습니다.
      • 사용: 보안이 중요한 웹사이트(온라인 쇼핑, 뱅킹, 로그인 페이지 등)에서 필수적으로 사용됩니다.
    • 왜 HTTPS를 사용해야 하는가?
      • 데이터 보호: HTTPS는 데이터를 암호화하여 사용자의 개인 정보와 민감한 데이터를 보호합니다.
      • 신뢰성: 사용자와 웹사이트 간의 신뢰를 구축합니다. 브라우저는 HTTPS를 사용하지 않는 사이트에 대해 경고를 표시할 수 있습니다.
      • SEO 이점: 검색 엔진(특히 Google)은 HTTPS를 사용하는 웹사이트를 선호합니다. 이는 검색 순위에 긍정적인 영향을 미칠 수 있습니다.
      • 데이터 무결성: HTTPS는 데이터가 전송 중에 변조되지 않도록 보호합니다.
      • 따라서, 보안이 중요한 모든 웹사이트는 HTTPS를 사용해야 하며, 대부분의 현대 웹사이트는 기본적으로 HTTPS를 사용하고 있습니다.

[241206 TIL]

대규모 AI 시스템 설계 프로젝트


1. 브랜치 생성 및 작업

Step 1: 브랜치 생성

develop 브랜치에서 새 브랜치를 생성합니다.

git checkout develop  # develop 브랜치로 이동
git pull origin develop  # 최신 상태로 동기화
git checkout -b feature/add-templates  # 새 브랜치 생성

2. 템플릿 파일 생성

.github 디렉터리와 템플릿 파일을 생성합니다.

Step 1: 디렉터리 생성

mkdir -p .github/ISSUE_TEMPLATE  # 이슈 템플릿 디렉터리 생성

Step 2: 파일 생성

# Bug Report 템플릿 생성
cat > .github/ISSUE_TEMPLATE/bug_report.md << EOF

내용 작성

EOF

# Feature Request 템플릿 생성
cat > .github/ISSUE_TEMPLATE/feature_request.md << EOF

내용 작성

EOF

# Pull Request 템플릿 생성
cat > .github/PULL_REQUEST_TEMPLATE.md << EOF

내용 작성

EOF

3. 변경사항 커밋 및 푸시

Step 1: 변경사항 확인

git status  # 변경된 파일 확인

Step 2: 스테이징

git add .github/  # .github 디렉터리 및 내부 파일 추가

Step 3: 커밋

git commit -m "feat: add issue and PR templates"

Step 4: 푸시

git push -u origin feature/add-templates

4. PR 생성

GitHub 웹사이트에서 feature/add-templates 브랜치에 대해 PR을 생성하고, 코드 리뷰를 요청합니다.


[241205 TIL]

JPA 도움닫기


REST API, Spring Security, JPA 연관관계와 영속성 컨텍스트 정리


1. REST API 메서드와 역할

REST API는 클라이언트-서버 간 통신을 위한 표준으로, 5가지 주요 메서드를 제공합니다.

REST API 메서드

  1. GET
    • 서버의 리소스에 액세스.
    • 데이터를 필터링하기 위해 쿼리 파라미터 사용 가능.
    • 예: GET /users?id=1
  2. POST
    • 데이터를 서버에 전송하여 리소스를 등록하거나 저장.
    • Body에 JSON, XML 등의 데이터를 포함하여 전송.
    • 예: POST /users (Body: { "name": "John" })
  3. PUT
    • 서버의 기존 리소스를 전체 업데이트.
    • 제공된 데이터로 리소스의 모든 필드를 수정.
    • 예: PUT /users/1 (Body: { "name": "John", "age": 30 })
  4. PATCH
    • 서버의 기존 리소스를 부분 업데이트.
    • 예: PATCH /users/1 (Body: { "name": "John" } → "name" 필드만 수정)
  5. DELETE
    • 리소스를 제거.
    • 인증 및 권한이 필요.
    • 예: DELETE /users/1

2. Spring Security - 인증과 인가

Spring Security는 애플리케이션 보안을 위한 강력한 도구로, **인증(Authentication)**과 인가(Authorization) 기능을 제공합니다.

Authentication (인증)

  • 사용자의 신원을 확인하는 과정.
  • 다양한 인증 방식을 지원:
    • Username/Password
    • OAuth2
    • Bearer Token
  • 인증 흐름: Authentication Filter에서 요청의 인증 정보를 추출 및 검증.

Authorization (인가)

  • 사용자의 권한을 확인하여 특정 리소스에 대한 접근 제어.
  • 엔드포인트 별로 권한을 설정할 수 있음:
    • /admin/** → ADMIN 권한 필요.
    • /users/** → USER 권한 필요.
    • /auth/** → 인증 불필요.
  • 설정 예:
    http.authorizeRequests()
        .antMatchers("/auth/**").permitAll()
        .antMatchers("/admin/**").hasRole("ADMIN")
        .anyRequest().authenticated();
    

3. JPA의 연관관계와 영속성 컨텍스트

JPA는 데이터베이스의 테이블 간 관계를 객체지향적으로 매핑하여 관리합니다.

JPA 연관관계

  1. 일대일(1:1)
    • 한 엔티티가 다른 엔티티와 1:1로 매핑.
    • 예: 상품 기본정보/상품 상세정보, 회원 정보/회원 프로필 정보.
  2. 일대다(1:N), 다대일(N:1)
    • 한 엔티티가 여러 개의 엔티티와 매핑.
    • 예: 게시글/좋아요, 주문/상품.
  3. 다대다(N:M)
    • 여러 엔티티가 여러 개의 다른 엔티티와 연결.
    • 예: 학생/과목, 게시글/태그.
    • 보통 중간 테이블을 사용하여 관리.

Persistence Context (영속성 컨텍스트)

JPA의 핵심 요소로, 엔티티 객체를 저장 및 관리하며 데이터베이스와의 작업을 효율화.

상태

  1. 비영속 (Transient)
    • 엔티티가 영속성 컨텍스트에서 관리되지 않는 상태.
  2. 영속 (Managed)
    • 엔티티가 영속성 컨텍스트에서 관리되는 상태.
    • 변경 감지(Dirty Checking), 쓰기 지연 등의 기능 지원.
  3. 준영속 (Detached)
    • 관리되던 엔티티가 영속성 컨텍스트에서 분리된 상태.
  4. 삭제 (Removed)
    • 엔티티가 삭제 상태로 표시되며, 트랜잭션이 끝나면 데이터베이스에서도 삭제.

장점

  • ACID 보장: 트랜잭션의 원자성, 일관성, 격리성, 지속성 보장.
  • 쓰기 지연 (Write-Behind)
  • 변경 감지 (Dirty Checking)

영속 상태로 만드는 방법

  1. @Transactional 선언.
  2. Repository에서 엔티티를 저장하거나 조회.

[241204 TIL]

프로젝트 관리 심화

대규모 스트림 처리 강의


 

⚠️ 트러블슈팅 ⚠️


1. 문제 정의

Kafka 실습 중 Docker Compose로 Kafka 환경을 구성했으나, Kafka UI에서 클러스터가 Offline 상태로 표시되고 정상적으로 동작하지 않음.


2. 원인 추론

  1. Docker 이미지 아키텍처 문제
    • Docker Desktop에서 "image may have poor performance, or fail if run via emulation" 경고 메시지가 출력됨.
    • 이는 Docker 이미지가 호스트 아키텍처와 일치하지 않아 발생.
  2. Kafka UI 타임아웃 문제
    • Kafka UI 이미지를 다운로드하는 과정에서 TLS handshake timeout 오류 발생.
    • 네트워크 문제 또는 Docker Hub와의 연결 문제로 인해 이미지 다운로드 실패.
  3. Docker Compose 설정 문제
    • 기존 docker-compose.yml 파일이 AMD64 아키텍처용 이미지로 구성되어 ARM64 호스트 시스템에서 실행 불가.

3. 해결 방안 및 결과

1) 호스트 아키텍처 확인

  • uname -m 명령어를 실행하여 호스트 시스템 아키텍처를 확인:
    uname -m
    
  • 출력 결과: arm64
    → 호스트 시스템이 ARM64 아키텍처임을 확인.

2) Docker Compose 이미지 교체

  • 기존 Docker Compose 파일에서 AMD64 전용 이미지ARM64 지원 이미지로 교체.

변경된 Docker Compose 파일:

version: '3.8'
services:
  zookeeper:
    image: confluentinc/cp-zookeeper:latest
    platform: linux/arm64
    ports:
      - "2181:2181"
    environment:
      ZOOKEEPER_CLIENT_PORT: 2181
      ZOOKEEPER_TICK_TIME: 2000

  kafka:
    image: confluentinc/cp-kafka:latest
    platform: linux/arm64
    ports:
      - "9092:9092"
    environment:
      KAFKA_ADVERTISED_LISTENERS: INSIDE://kafka:29092,OUTSIDE://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: INSIDE:PLAINTEXT,OUTSIDE:PLAINTEXT
      KAFKA_LISTENERS: INSIDE://0.0.0.0:29092,OUTSIDE://0.0.0.0:9092
      KAFKA_INTER_BROKER_LISTENER_NAME: INSIDE
      KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181

  kafka-ui:
    image: provectuslabs/kafka-ui:latest
    platform: linux/arm64
    ports:
      - "8080:8080"
    environment:
      KAFKA_CLUSTERS_0_NAME: local
      KAFKA_CLUSTERS_0_BOOTSTRAPSERVERS: kafka:29092
      KAFKA_CLUSTERS_0_ZOOKEEPER: zookeeper:2181
      KAFKA_CLUSTERS_0_READONLY: "false"

3) Kafka UI 이미지 수동 다운로드

  • Kafka UI 다운로드 시 타임아웃 오류 해결을 위해 수동으로 이미지를 다운로드:
    docker pull provectuslabs/kafka-ui:latest
    
  • 수동 다운로드 완료 후, docker-compose up 명령어로 다시 실행.

결과

  1. Kafka UI에서 클러스터가 Online 상태로 표시됨.
  2. Zookeeper, Kafka, Kafka UI 모두 ARM64 환경에서 정상 실행.
  3. Kafka 실습을 성공적으로 진행 가능.

+ Recent posts