Skip to content

아키텍처 개요

데이터베이스 컬럼명을 표준화하기 위한 단어사전 관리 도구다. 컬럼명은 대개 여러 단어와 도메인을 조합해 만들므로, 이때 쓰는 단어와 도메인을 데이터베이스에서 관리한다.

사용자가 단어를 입력하면 이를 잘라 각 단어에 맞는 영문 토큰(단축어)을 찾는다. 찾은 단축어를 언더바(_)로 잇고 마지막에 도메인을 붙여 최종 컬럼명을 돌려준다. 데이터베이스에 없는 단어는 한영사전에서 후보 영단어를 찾아 보여주고, 사용자가 그중 하나를 골라 새 단어로 등록할 수 있다.

dictionary-app (프런트엔드)

React 19 + Vite(Rolldown) + TypeScript, Chakra UI v3. TanStack Query·React Router·React Hook Form + Zod·Zustand·ag-grid 사용. GitHub Pages로 배포.

dictionary-api (백엔드)

Java 26 + Spring Boot 4.1.0 + Gradle. 레이어드 구조(controller/service/repository) + Spring Data JPA/QueryDsl/Flyway. Render로 배포.

외부 사전 API

국립국어원 한영사전(krdict, 영어 번역) 오픈 API를 백엔드가 대신 호출해 후보 영단어를 조회한다. 표준국어대사전(stdict, 뜻풀이) 조회 API(/v1/search/find-stdict)도 백엔드에 있지만, 현재 프런트엔드에서는 사용하지 않는다.

flowchart LR
  app["dictionary-app<br/>React 19 · GitHub Pages"]
  api["dictionary-api<br/>Spring Boot 4 · Render"]
  db[(단어사전 DB)]
  ext["국립국어원<br/>한영사전 API (krdict)"]

  app -- "① 단어사전 조회<br/>GET /v1/dictionary/find-by-kor-nm" --> api
  app -. "② DB에 없는 단어일 때만<br/>GET /v1/search/find-krdict" .-> api
  api --> db
  api -.-> ext
  • 프런트엔드는 axios로 호출한다. baseURL은 빌드 시 고정되는 Vite 환경변수 VITE_APP_API_URL이고, withCredentials: true로 세션 쿠키를 실어 보낸다.
  • DB에 없는 단어인지는 프런트엔드가 판단한다. 컬럼명 생성 화면은 단어마다 단어사전 조회 API(/v1/dictionary/find-by-kor-nm/{korNm})를 먼저 호출한다. 결과가 비어 있을 때만 한영사전 검색 API(/v1/search/find-krdict/{word})를 추가로 호출한다.
  • 백엔드의 한영사전 검색 API는 DB를 거치지 않고, 외부 사전 API(KrdictClient) 호출 결과만 돌려준다.

세션 기반 인증이며 JWT를 사용하지 않는다.

  • 백엔드는 spring-session-jdbc로 로그인 세션을 DB(SPRING_SESSION 테이블)에 저장한다. 운영(prod) 환경은 메모리 H2 DB를 쓰므로, 서버가 재시작되면 세션이 모두 사라진다.
  • 로그인(POST /v1/auth/login)하면 서버가 세션을 만든다. 게스트는 POST /v1/auth/guest-login으로 로그인한다. 이후 프런트엔드는 모든 요청에 세션 쿠키를 자동으로 실어 보낸다.
  • 인가는 Spring Security 필터체인이 아니라 AuthorizationInterceptor가 맡는다. 화이트리스트(fail-closed) 방식이라 @PublicApi가 없는 API는 모두 로그인이 필요하다.
  • 게스트 계정(guest_yn = 'Y')이 @GuestForbidden이 붙은 API를 호출하면 403으로 거부된다. 주로 생성/수정/삭제 API에 붙지만, 파일 다운로드(GET /v1/file/download/{fileKey})와 도구 API(/v1/tools/**) 같은 조회성 API에도 붙어 있다.

프런트엔드 — GitHub Pages

dictionary-app 저장소의 deploy 브랜치에 push되면 GitHub Actions가 빌드 후 GitHub Pages로 배포한다. master는 통합 브랜치일 뿐 배포를 트리거하지 않는다.

백엔드 — Render

dictionary-api 저장소의 deploy 브랜치에 push되면 Docker 이미지로 빌드되어 Render에 배포된다. 무료 티어 슬립 방지를 위해 10분 간격으로 /actuator/health를 호출하는 keep-alive 워크플로우가 있다.

로컬에서 전체 스택(MySQL + 백엔드 + 프런트엔드)을 한 번에 띄우려면 dictionary-api의 docker-compose.yml(docker 프로파일)을 쓴다. 세 컨테이너는 dictionary-net 브리지 네트워크로 묶인다.