목록
API 서버 대표 이미지

AI-Ready 홈페이지 API 서버

1. 프로젝트 개요

이 프로젝트는 AI-Ready의 공식 홈페이지에 필요한 데이터를 제공하는 백엔드 API 서버입니다. Spring WebFlux 기반의 비동기/논블로킹 방식으로 구현되어 높은 성능과 확장성을 목표로 합니다.

주요 기능은 블로그(기술, 연구, 소식 등) 컨텐츠 관리, 사용자 인증, 문의사항 처리, 파일 관리 등을 포함합니다.


2. 기술 스택

  • 언어: Java 17
  • 프레임워크: Spring Boot 3.x, Spring WebFlux (Reactive-Stack)
  • 데이터베이스: RDBMS (MySQL, PostgreSQL 등)
  • 데이터베이스 연동: R2DBC (Reactive Relational Database Connectivity)
  • 인증: JWT (JSON Web Token)
  • 빌드 도구: Gradle
  • 기타: Lombok, Logback



3. 아키텍처: 왜 Spring WebFlux를 선택했는가?


이 프로젝트는 전통적인 Spring MVC 방식이 아닌 Spring WebFlux 기반의 리액티브(Reactive) 프로그래밍 모델을 채택했습니다. 그 이유는 AI 시대의 서비스가 요구하는 특성에 더 잘 부합하기 때문입니다.

전통적인 MVC 방식의 한계

  • Thread-Per-Request 모델: 사용자의 요청마다 하나의 스레드가 할당됩니다. 만약 데이터베이스 조회나 외부 API 호출과 같은 I/O 작업이 길어지면, 해당 작업이 끝날 때까지 스레드는 **블로킹(Blocking)**되어 다른 일을 하지 못하고 대기합니다.
  • 리소스 비효율성: 동시 접속자가 많아지고, 각 요청의 처리 시간이 길어질수록(예: LLM 호출), 스레드 풀의 스레드가 빠르게 고갈됩니다. 이는 서버 전체의 응답성 저하와 리소스 낭비로 이어집니다.

WebFlux (Reactive) 방식의 장점

  • 이벤트 루프(Event-Loop) 기반 논블로킹(Non-Blocking): 최소한의 스레드(일반적으로 CPU 코어 수와 동일)를 사용하여 모든 요청을 처리합니다. I/O 작업이 발생하면 스레드가 결과를 기다리지 않고 즉시 다른 요청을 처리하러 갑니다. 작업이 완료되면 콜백(Callback)을 통해 결과를 받아 후속 처리를 이어갑니다.
  • 높은 동시성과 확장성: 스레드가 블로킹되지 않으므로, 적은 리소스로도 훨씬 많은 동시 요청을 효율적으로 처리할 수 있습니다. 이는 수많은 동시 사용자를 가정해야 하는 최신 웹 서비스에 필수적입니다.

AI 시대에 WebFlux가 필수적인 이유

AI 서비스, 특히 외부 LLM(거대 언어 모델) API를 호출하는 작업은 네트워크 지연 시간으로 인해 수 초 이상이 소요될 수 있는 대표적인 고지연(High-Latency) 작업입니다.

  • 효율적인 리소스 관리: WebFlux를 사용하면 LLM API가 응답을 기다리는 동안 스레드는 다른 수십, 수백 개의 요청을 처리할 수 있습니다. 이는 서버 리소스를 극적으로 아끼고, 높은 트래픽 상황에서도 안정적인 서비스를 제공하는 핵심 요소가 됩니다.
  • 스트리밍 응답에 최적화: AI 모델이 생성하는 텍스트를 실시간으로 사용자에게 보여주는 것과 같은 스트리밍(Streaming) 응답을 자연스럽게 지원합니다.

💡 결론적으로, Spring WebFlux는 AI 연동과 같이 예측 불가능하고 긴 I/O 작업이 빈번한 환경에서 서버의 반응성과 확장성을 극대화하는 최적의 아키텍처입니다.


4. 프로젝트 구조

.
├── build.gradle              # Gradle 빌드 스크립트
├── gradlew                   # Gradle Wrapper
├── settings.gradle           # Gradle 설정
├── start.sh                  # 애플리케이션 실행 스크립트
├── stop.sh                   # 애플리케이션 중지 스크립트
├── src
│   ├── main
│   │   ├── java
│   │   │   └── com/aiready
│   │   │       ├── Application.java      # 메인 애플리케이션 실행 클래스
│   │   │       ├── aspect                # AOP 관련 클래스 (파라미터 유효성 검증 등)
│   │   │       ├── config                # 애플리케이션 주요 설정 (보안, DB, CORS 등)
│   │   │       ├── controller            # API 엔드포인트 정의
│   │   │       ├── exception             # 전역 예외 처리
│   │   │       ├── model                 # 데이터 모델 (DTO, Entity 등)
│   │   │       ├── repository            # 데이터베이스 접근 로직 (R2DBC)
│   │   │       ├── service               # 비즈니스 로직
│   │   │       └── util                  # 유틸리티 클래스 (JWT 토큰 생성 등)
│   │   └── resources
│   │       ├── application.yml       # 공통 설정 파일
│   │       ├── application-dev.yml   # 개발 환경 설정 파일
│   │       ├── application-prod.yml  # 운영 환경 설정 파일
│   │       ├── i18n                    # 다국어 메시지 프로퍼티
│   │       ├── logback-spring.xml      # 로깅 설정
│   │       └── mapper                  # SQL 쿼리 XML 파일
│   └── test                    # 테스트 코드
└── hep
    ├── scheme.sql              # 데이터베이스 테이블 생성 스키마
    └── ERD-homepage-*.erwin    # ERD 파일

5. 개발 환경 설정

  1. 사전 요구사항

    • Java 17 (JDK 17) 설치
    • IDE (IntelliJ IDEA 또는 Eclipse) 설치
    • 데이터베이스 (MySQL, PostgreSQL 등) 설치 및 실행
  2. 프로젝트 클론

    git clone [저장소 URL]
    cd 2025_aiready_homepage_api
    
  3. 데이터베이스 설정

    1. hep/scheme.sql 파일을 사용하여 프로젝트에서 사용할 데이터베이스에 테이블을 생성합니다.
    2. 데이터베이스 사용자 계정을 생성합니다.
  4. 애플리케이션 설정

    1. src/main/resources/application-dev.yml 파일을 엽니다.
    2. spring.r2dbc 섹션에 자신의 로컬 데이터베이스 접속 정보를 입력합니다.
      spring:
        profiles:
          active: dev # 개발 시 'dev' 프로파일 활성화
        r2dbc:
          url: r2dbc:mysql://{DB_HOST}:{DB_PORT}/{DB_NAME}
          username: {DB_USERNAME}
          password: {DB_PASSWORD}
      
    3. (선택) JWT 토큰 생성에 사용될 jwt.secret 값을 변경합니다.



6. 빌드 및 실행

IDE에서 직접 실행

  1. IntelliJ IDEA에서 Application.java 파일을 엽니다.
  2. main 메소드 옆의 실행 버튼을 클릭하여 애플리케이션을 시작합니다.

Gradle을 사용하여 실행

터미널에서 아래 명령어를 실행하여 애플리케이션을 빌드하고 실행할 수 있습니다.

# 프로젝트 빌드
./gradlew build

# 애플리케이션 실행
./gradlew bootRun

애플리케이션이 정상적으로 실행되면 localhost:8080 (또는 application-dev.yml에 설정된 포트)에서 API 서버가 활성화됩니다.


7. 주요 기능 및 API 엔드포인트

  • AuthController: 회원가입, 로그인 등 사용자 인증 관련 API
  • UserController: 사용자 정보 조회 및 수정 API
  • TechBlogController: 기술 블로그 게시물 CRUD API
  • NewsBlogController: 소식 블로그 게시물 CRUD API
  • LabBlogController: 연구 블로그 게시물 CRUD API
  • InquiryController: 문의사항 등록 및 조회/답변 API
  • FileStorageController: 파일 업로드/다운로드 API

💬 상세한 API 명세는 Postman 컬렉션이나 API 문서를 참고하세요.


8. 데이터베이스

  • 본 프로젝트는 R2DBC를 사용하여 비동기적으로 데이터베이스와 통신합니다.
  • SQL 쿼리는 src/main/resources/mapper 디렉토리의 .xml 파일에 정의되어 있습니다.
  • com.farm 패키지는 XML에 정의된 동적 SQL을 파싱하고 실행하는 커스텀 SQL 매퍼 엔진입니다. 이를 통해 MyBatis와 유사한 방식으로 동적 쿼리를 관리할 수 있습니다.



9. 인증

  • API 접근 제어는 JWT(JSON Web Token)를 통해 이루어집니다.
  • 사용자가 로그인을 성공하면 서버는 Access Token과 Refresh Token을 발급합니다.
  • 인증이 필요한 API를 호출할 때는 HTTP 헤더에 Authorization: Bearer {Access_Token} 형식으로 토큰을 포함해야 합니다.
  • JwtTokenProvider 클래스에서 토큰 생성 및 검증 로직을 확인할 수 있으며, SecurityConfig에서 라우트별 접근 권한을 설정합니다.



10. 서비스 배포

  • start.sh, stop.sh, hp_api.service 파일들은 Linux 환경에서 서비스를 배포하고 관리하기 위한 스크립트입니다.
  • hp_api.servicesystemd 서비스로 등록하여 서버 부팅 시 자동으로 애플리케이션을 실행하도록 설정하는 데 사용될 수 있습니다.