블로그 리팩토링 프로젝트 -1- (Feat. RESTful API)

프로필

2025년 03월 12일

66 0

슬슬 바쁜 일정들이 얼추 정리되면서 미루고 미뤄왔던 프론트엔드 Next.js 도입을 시작하려고 한다.
하지만 난 프론트엔드에 대해서는 아는게 부트캠프 과정 중에 한 일주일 정도 집고 넘어갔던 HTML + CSS + JavaScript 정도 밖에 없다. 실제로 지금 이 블로그도 저 세 개의 조합으로 이루어져있고, MusicLab 프로젝트에서 프론트엔드와의 협업을 진행하기 전에 직접 shadcn을 이용하기 위해서 AI와 함께 눈물의 똥꼬쇼를 진행했던 적이 있는데 결국 실패해서 섭외를 고민하게 되었었다.

하지만 지금은 부트캠프도 끝났고, 그때 함께 작업했던 프론트엔드 분도 지금은 취준으로 바빠서 도와달라고 할 엄두가 안나기도 하고, 지금은 그때완 다르게 Claude의 Sonnet 3.7나 OpenAI의 o3-mini-high 등의 코딩 특화 AI의 폼이 많이 올라와서 혼자 도전해보려고 한다. 언제까지나 저 과거의 유산 같은 조합을 이용할 수는 없을테니까.

도입을 하려고 어느 정도 정보를 찾아보던 중에 깨달은 점이 있는데 현 상황에서 Next.js를 도입하려면 지금 내 FastAPI의 엔드포인트들을 RESTful하게 수정해야 한다는 사실을 알았다.

그 이유로는 크게 두 가지 정도가 있는데
1. 데이터 통신 표준화
- Next.js의 fetch() 및 getServerSideProps가 기대하는 GET/POST/PUT/DELETE 메소드와 엔드포인트 구조를 맞추기 위해
2. 리소스 중심 아키텍처
- 계층적 URL 구조로 /users/{id} 형태의 엔드포인트가 Next.js의 동적 라우팅(pages/users/[id].js)과 자연스럽게 연동
- 버전 관리에도 용이(/api/v1/ 접두사 사용으로 향후 API 변경 시 하위 호환성 유지 가능)

이 사실을 알고나서 내 API들의 엔드포인트와 HTML 메소드, 실제 구조들을 살펴보니 개판도 이런 개판이 없었다. 전부 여기 기재하면 글이 너무 길어질 것 같아 문제점 몇개만 꼽아보자면
1. RESTful 원칙 미준수
- 리소스 조회에 때로는 GET, 때로는 POST 사용
- 로그아웃에 GET 사용
2. 일관성 없는 URL 구조와 액션 기반 URL 구조
- 어떤 액션은 /edit/{post_id}처럼 액션이 먼저 표시
- 어떤 액션은 /post/{post_id}/toggle-publish처럼 리소스가 먼저 표시
- RESTful API는 리소스 중심이어야 하지만 위의 경우처럼 일관성도 없을 뿐더러 많은 엔드포인트가 액션 중심으로 구성되어 있음(/delete/{post_id}, /post/{post_id})
3. 중복 엔드포인트
- 동일한 URL에 두 가지 메소드 사용
- /write의 경우 GET으로 UI 렌더링, POST로 게시글 등록

몇개만 꼽아보자고 했지만 다시금 이렇게 보니 정말 개판이다. 그래서 일단 개념만 얼추 알고있던 RESTful API 설계에 대해서 내가 알아본 점에 대해서 설명을 하려고 한다.

RESTful API란?

REST(Representational State Transfer) 아키텍처 스타일의 설계 원칙을 준수하는 API

RESTful API의 특징

  1. 리소스 중심 구조 : URI를 통해 리소스를 명확히 표현
  2. HTTP 메소드 활용 : GET, POST, PUT, DELETE 등의 HTTP 메소드로 리소스에 대한 CRUD를 수행
  3. 무상태성(Stateless) : 모든 요청은 독립적이며, 서버는 클라이언트의 상태를 저장하지 않음
  4. 캐시 가능성 : 응답을 캐싱하여 성능 향상이 가능
  5. 클라이언트-서버 구조 : 클라이언트와 서버의 역할이 명확하게 분리됨
  6. 계층화 : 보안, 로드 밸런싱 등을 위해 다중 계층으로 구성될 수 있음
  7. 인터페이스 일관성 : 표준화된 방식으로 정보를 주고 받아 시스템 간 통합을 용의하게 함

사실 여기서 내가 지키고 있는 건 단 하나도 없었다. 위에서 언급했듯이 리소스 중심이 아닌 액션 중심의 엔드포인트로 설계했고, 심지어 몇개는 리소스 중심이며 일관성 조차 없었다. HTML 메소드도 PUT, DELETE 등을 거의 사용하지 않았다.

언젠가 부트캠프 과정중에 멘토님이 내 블로그가 아닌 타 수강생의 웹 어플리케이션을 보면서 현재 내 구조와 같이 edit/{id} 이런 식으로 짜지 말라고 한 걸 옆에서 주워들었었는데 그때 당시엔 이게 뭔소리지 싶었지만 지금 보니까 경험에서 우러나온 짬바였단 걸 다시금 깨닫게 되었다.

그래서 어떻게 설계해야 하는가?

RESTful API 설계를 할 때 가장 중요한 건 URI는 리소스를 표현하고, 행위는 HTTP 메서드로 표현해야 한다는 것이다. 이걸 제대로 이해하면 API가 깔끔하고 일관성 있게 나온다.

1. URI는 정보의 리소스를 표현해야 한다

API에서 URI는 무조건 명사 기반으로 작성해야 한다. 동사를 써서 API를 설계하면 RESTful하지 않은 API가 된다.

❌ 나쁜 예:

/getUsers, /createProduct, /updatePost, /deleteComment

⭕ 좋은 예:

/users, /products, /posts, /comments
  • 리소스 그룹(컬렉션)은 복수형으로 작성한다 = 지금의 나처럼 하면 안된다는 소리다.
  • 단일 리소스는 단수형으로 작성한다.

2. HTTP 메소드 행위를 표현한다

CRUD 기능을 만들 때, 리소스 자체는 URI에서 표현하고 행위는 HTTP 메서드를 사용해야 한다.
- 생성(Create) -> POST(/posts)
- 조회(Read) -> GET(/posts/1)
- 수정(Update) -> PUT(/posts/1)
- 삭제(Delete) -> DELETE(/posts/1)

❌ 잘못된 예:

GET /posts/show/1
POST /posts/insert/2

⭕ 올바른 예:

GET /posts/1
POST /posts

3. 리소스 간 계층 구조를 반영해야 한다

리소스 간에 종속 관계가 있을 때, 슬래시(/)를 이용해 계층 구조를 나타내야 한다.
예를 들어, 특정 게시물의 댓글을 가져오고 싶다면?

❌ 잘못된 예:

GET /comments?postId=1

⭕ 올바른 예:

GET /posts/1/comments

4. URI 끝에 슬래시(/) 넣지 않기

REST API는 깔끔한 URI를 유지하는 게 중요하다. URI 마지막에 /를 붙이면 혼란만 가중된다. (이 부분은 ELK스택의 NGINX 리버스 프록시 설정에서 그 중요성을 뼈저리게 느꼈었다.)

❌ http://api.example.com/users/
⭕ http://api.example.com/users

5. URI에는 소문자만 사용하기

대문자를 사용하면 API가 대소문자를 구별할 수도 있고, 혼란을 유발할 수 있다. RFC 3986(URI 문법 형식)에서도 URI는 소문자로 작성하는 것을 권장한다.

❌ /Users/Kim
⭕ /users/kim

6. 하이픈(-)을 사용해 가독성 높이기

언더스코어( _ )대신 하이픈(-)을 사용하면 더 읽기 쉬워진다. (이 부분은 파이썬의 국룰인 스네이크 케이스와 달라서 좀 헷갈리는 부분이 있다.)

❌ /products/electronics/computer_accessories
⭕ /products/electronics/computer-accessories

7. 쿼리 매개변수를 활용한 필터링, 정렬, 페이지네이션

컬렉션을 다룰 때는 쿼리 매개변수를 활용해 검색, 필터링, 정렬을 적용할 수 있다.

/users?name=Kim&age=25&sort=asc&page=2

이처럼 직관적인 키워드를 사용해야 한다.

❌ 나쁜 예: /users?q=Kim&f=25&o=asc&l=2
⭕ 좋은 예: /users?name=Kim&age=25&sort=asc&page=2

8. 특정 동작이 필요할 땐 동사를 사용

CRUD 이외의 특별한 동작(활성화, 비활성화, 승인 등)은 동사를 사용해서 API를 명확하게 만들어야 한다.

❌ 잘못된 예: /users/1/status
⭕ 올바른 예: /users/1/activate
❌ 잘못된 예: /products/123/delivery
⭕ 올바른 예: /products/123/send

결론

일단 이런 특징과 설계 방향을 따라서 설계를 해보려고 시도는 해봤는데, 아까 현 상태에서 잘못된 설계라고 언급했던 GET/POST를 동시에 사용하는 /write의 경우도 RESTful 하게 설계하려면 저장 API만 /posts로 넘기고 UI 렌더링을 진행하는 GET API는 따로 /write 라우트로 분리해서 렌더링만 담당하게 해야 하지만 그렇게 되면 구조가 더러워질 거 같아서 엄격하게 RESTful 규칙을 적용해야 할 지, 아니면 큰 틀은 따라가되, 어느 정도의 유연함을 적용할지 고민을 더 해봐야할 것 같다. 그래서 일단은 FastAPI의 엔드포인트 및 구조 리팩토링은 조금 뒤로 미뤄두고 일단 Next.js를 빌드해서 현 구조와 엮어보고 정상 동작하는 지 확인한 뒤 차후에 진행해야할 것 같다.

#REST #RESTful #RESTful API

댓글 개

댓글을 작성하려면 로그인이 필요합니다