'What is RESTful API?' 의 내용이 아니라😂
최근 API를 설계했던 경험에 대해 공유하는 글이에요.
자소설닷컴의 백엔드 애플리케이션은 Ruby on Rails로 만들어져 있지만,
RESTful API는 함께 생각해볼 수 있을것 같아요.😄
이번 작업은 자소설닷컴의 채팅 서비스를 약간 업그레이드 하는 것 이었어요.
개인별로 채팅목록을 좀 더 편하게 관리할 수 있도록 했습니다.
저는 백엔드 애플리케이션과, iOS클라이언트 작업을 진행했어요.
다음 글에서는 iOS개발 과정에서 있었던 이슈들을 공유해 볼게요🏃🏻♂️
채팅 리스트 - 그룹별로 섹션이 나누어져 있지만, 유저가 다룰 수 없어요. 정해진 섹션을 서버에서 보내주고 있습니다.
내 채팅 - 유저가 참여한 채팅방 리스트. 에디팅 모드는 없고, 채팅방 안에서 '나가기'를 할 수 있어요.
위와 같았던 채팅리스트를 앞으로는 좀 더 유저가 사용하기 편하게 바꾸려 하고 있어요!
이번에는 크게 3가지 요구사항이 있었습니다.👀
더 있는것 같은데, 백엔드 관련해서는 이정도로 추릴 수 있을것 같아요!
기존에는 User, Chat, ChatUser 정도로 채팅 서비스를 운영하고 있었어요.
User와 Chat은 M:N관계로 chat_users를 조인 테이블로 이용했어요.
그래서 내가 참여하고 있는 채팅방들은 다룰 수 있었습니다.
하지만 이제 내가 참여한 채팅방들을 그룹별로 관리할 수 있도록 해야해서, ChatGroup 을 새로 만들었어요.
User : ChatGroup = 1 : N
ChatGroup : Chat = M : N
의 형태입니다.
먼저 채팅그룹 리소스를 다루는 API를 만들었어요.
namespace :api, defaults: { format: :json } do
namespace :v1 do
...
resources :chat_groups, path: 'chat-groups', only: [:index, :update]
end
end
config/routes.rb
레일즈 코드입니다
GET /api/v1/chat-groups
PATCH(PUT) /api/v1/chat-groups/:id
두개의 엔드포인트가 생성되요. 기본적인 형태죠?
하지만 이것은 ChatGroup에 '바로' 접근하는 형태라 마음에 들지 않았어요.
저는 'User'의 ChatGroup리소스를 다루고 싶었거든요.
그래서 chat-group 앞에 user를 붙이기로 했어요!
그런데 두 가지 생각해 볼 부분이 있었어요..🤣
첫번째는 복수형이냐 단수형이냐 문제입니다.
보통 API에서 리소스를 다룰때, 복수형으로 하곤 하잖아요?
그래서 저도 처음에 복수형 resources를 이용했습니다.
namespace :api, defaults: { format: :json } do
namespace :v1 do
...
resources :users, only: [] do
resources :chat_groups, path: 'chat-groups', only: [:index, :update]
end
end
end
config/routes.rb
결과는
GET /api/v1/users/:user_id/chat-groups
라는 엔드포인트가 만들어졌습니다!
하지만 또 마음에 들지 않았어요😱
이 형태는 전체 유저풀에서 user_id로 유저를 조회해, 그 유저의 chat_groups 를 찾는 느낌이랄까요?
물론 이것도 틀린 것은 아니에요. 경우에 따라 필요하고, 쓸 수 있는 형태라고 생각합니다!
그래서 일단 's'를 빼고 단수형으로 바꿔봤습니다.
...
resource :users, only: [] do
...
이제 GET /api/v1/user/:user_id/chat-groups
가 되었습니다!
그래도 아직이더라구요.🥶😥
이번에 필요한 API는 '나의 채팅그룹들' 을 조회하는 엔드포인트였어요!
내 것을 찾으면 되는데, 쿼리 파라미터로 user_id를 넘겨 리소스를 조회 하는것은 좀 이상하다? 생각했어요.
레일즈 라이브러리인 Devise에서는 user_signed_in?
이나 current_user
라는 메소드도 이미 존재하고 있고,
컨트롤러에서 before_action :authenticate_user!
로 로그인을 강제할 수 있기 때문에, 파라미터로 user_id를 넘기지 않기로 결정했습니다!
그래서 resource키워드 대신, namespace를 사용하기로 했어요🤗
namespace :api, defaults: { format: :json } do
namespace :v1 do
...
namespace :user do
resources :chat_groups, path: 'chat-groups', only: [:index, :update]
end
end
end
config/routes.rb
최종적으로
1. GET /api/v1/user/chat-groups
2. PATCH /api/v1/user/chat-groups/:id
의 형태가 되었어요.✌🏻
길이 좀 글어지는것 같아 나누어서 포스팅 하겠습니다!
'Deep Dive'라고 했지만 여기까지는 사실 큰 고민 없었고,
다음 편에서 이야기할 부분이 좀 볼만 하실 것 같아요😅
'many to many 관계를 끊어주는 엔드포인트?' 로 다음 포스팅을 이어가겠습니다!
두번째 찬준👏