이얏호 중간 발표가 끝나고 드디어 제대로 된 개발 시작!
저번 주에는 MSA 구조 고민하고, ERD 하루 종일 만드느라..
이번 주 월요일과 화요일에는 중간 발표를 위한 PPT를 만드느라 정신이 없었다.
피그마부터 피피티까지! 이정도면 나름.. 디자이너가 됐다고 봐도 무방하다. 실력은 그렇지 못하지만..
그리고 중간 프로젝트처럼 이번에도 발표를 맡게 되었다.
발표 10분에 질의응답만 30분!을 받았는데 이 내용은 다음 글에 자세히 정리해보겠다.

그럼 이제 진짜 본론으로!

매매 기능을 구현하기 위해 user와 group 컨트롤러를 보다가 이상한 부분을 포착했다.
바로 RequestMapping 어노테이션에서 왼쪽의 유저는 ("/api/users) 오른쪽의 그룹 ("/group")인 점이다.
사실 난 항상 접두사로 "/api"를 습관처럼 붙여왔는데 왜 사용하는지, 꼭 필수로 사용해야하는지는 정확히 모르고 있었다. 그래서 이번 기회에 정확하게 정리해보았다!
1. 정적 리소스와 구분해야 할 때
Springboot에서는 /resource/static 폴더 내에 HTML, CSS, JS 등 정적 리소스를 둘 수 있다.
예를 들어, /api/users라는 API와 /users.html이라는 정적 리소스가 함께 존재한다고 가정해 보자.
만약 api/ 접두사를 사용하지 않는다면 다음과 같은 상황이 생긴다.
/users (API)
/users.html (정적 리소스)
이 경우 프론트엔드에서 users를 호출할 때, 이것이 API 요청인지 정적 파일 요청인지 혼동될 수 있다.
👉 이런 문제를 방지하기 위해 API에는 /api 접두사를 붙여 구분하는 것이 일반적이다.
다만 React.js, Next.js 등 프론트엔드 프레임워크를 사용해 정적 리소스를 별도로 서빙하는 경우에는 이러한 충돌이 직접적으로 발생하지 않는다.
2. 프론트엔드와 백엔드가 같은 도메인을 사용할 때 (feat. 리버스 프록시)
✔ 같은 도메인 (예: togather.com)
Nginx 혹은 CloudFront와 같은 리버스 프록시를 사용하면, 프론트엔드와 백엔드의 도메인 주소를 같게 맞춰줄 수 있다. 이 경우, 라우팅이 충돌할 수 있다.
예를 들어, /trading이라는 경로가 프론트 페이지인지, 백엔드 API인지 구분하기 애매해진다.
👉 이런 문제를 피하려면 /api 접두사를 붙여 명확하게 구분하는 것이 사실상 필수다.
✔ 다른 도메인 (예: togather.com vs api.togather.com)
프론트와 API 서버가 아예 다른 도메인을 사용한다면 경로 충돌은 발생하지 않는다. 이 경우 /api 접두사는 선택사항이 된다. 추가로, 다른 도메인을 사용하는 경우에는 CORS 설정을 반드시 해주어야 한다.
3. 프론트엔드 입장에서 명확하다!
설령 /api 접두사가 필수가 아닌 상황이라 하더라도,
경로를 /api로 통일하면 프론트엔드 입장에서 API 요청임이 명확하다.
또한 가독성이 높아지고, 업계 관례상 /api를 사용하는 것이 일반적이므로 일관성을 유지할 수 있다.
그래서 우리 팀은 어떻게 하기로 했을까?
1. 우리 서비스는 프론트엔드를 Next.js를 써서 정적 리소스 충돌 문제는 발생하지 않는다.
2. 하지만, MSA 구조에서 Gateway가 리버스 프록시 역할을 하므로 같은 도메인에서 프론트와 백엔드를 함께 서비스한다.
3. 게다가 프론트엔드 입장에서도 /api로 구분하면 훨씬 명확하다.
👉 결론적으로 우리는 /api를 사용하기로 했다. /api는 선택이 아니라 필수에 가깝다.
하지만 한 가지 더 고민이 있었다.
@RequestMapping("/api/users")
@RequestMapping("/users")
MSA + 게이트웨이 구조에서 내부 서비스에도 /api를 붙여야 할까?
아니면 게이트웨이에서만 붙이고, 내부는 도메인 단위로 단순하게 가져가는 게 맞을까?
MSA + 게이트웨이 구조에서의 /api
우리 팀은 이렇게 결정했다:
외부 진입점(게이트웨이): 프론트엔드 입장에서는 API가 하나처럼 보이도록 /api를 통일
내부 서비스: 각 서비스는 자기 도메인 중심 경로만 관리
// 외부 진입점 (게이트웨이): 프론트엔드 입장에서는 API가 하나처럼 보이도록 /api를 통일
/api/user
/api/trading
/api/vote
// 내부 서비스: 각 서비스는 자기 도메인 중심 경로만 관리
/user
/trading
/vote
즉, 게이트웨이가 /api를 붙여주고, 내부로 들어올 때는 잘라내서 전달하는 구조이다.
Spring Cloud Gateway 설정 (application.yml)
spring:
application:
name: api-gateway
cloud:
gateway:
routes:
# 사용자 서비스
- id: user-service
uri: http://user-service:8080
predicates:
- Path=/api/users/**
filters:
- StripPrefix=1 # /api 제거
filters: StripPrefix=1을 사용하면 게이트웨이에서 /api를 떼고 내부 서비스로 전달할 수 있다.
따라서 내부에서는 이렇게만 작성하면 된다:
@RestController
@RequestMapping("/users")
public class UserController {
}
최종적으로 아래와 같이 수정했다.
👉 이렇게 하면 프론트엔드에는 /api가 일관되게 노출되고,
내부 서비스는 불필요하게 /api를 중복해서 가질 필요가 없으니 훨씬 깔끔하다.
'[프디아] 파이널 프로젝트' 카테고리의 다른 글
[신투 프디아] 그룹 단위 주식 공동 매매 - 결제는 정수, 거래는 소수 (0) | 2025.10.17 |
---|---|
[신투 프디아] MSA 좋은 듯 어렵다 - 왜 투게더는 MSA로 설계했을까? (2) | 2025.10.11 |
[신투 프디아] ERD 트레이딩 시스템 개선기 - 왜 다시 설계했을까? (1) | 2025.09.26 |
[신투 프디아] 파이널 프로젝트 '투게더' 기획 (2) | 2025.09.19 |