유연한 태도 갖기
빈츠 블로그
며칠 전에 "Create / Update 시 응답에 변경된 리소스를 포함해야 할까?"라는 제목으로 글을 쓴 적이 있다. 여기서 나는 대부분의 경우에 Create나 Update 작업 시 API 응답에 변경된 리소스를 포함해야 한다는 의견이었다. 글을 쓰고 난 지 얼마 안돼서 구글 파이어베이스 시니어 개발자님의 웨비나를 듣게 되었는데, 이번에도 궁금해서 질문을 드렸다.
사실 웨비나 주제가 흥미로워서 듣게 된 거라 질문 자체에는 크게 기대를 하지 않았다. 그런데도 답변을 듣고나서, 웨비나가 끝난 다음에도 한참을 생각했다. 그래서 내가 내린 결론은 나무가 아닌 숲을 봐야한다는 것이다. 나는 사람들이 같은 말이라도 자신만의 경험에 따라 각기 다르게 받아들이고, 해석한다고 생각한다. 나는 그렇게 알아들었다.
결국 팀을 위한 선택을 해야한다. API 응답에 무엇을 담든지 개인 취향의 문제일 수도 있고, 팀의 컨벤션일 수도 있고, 저마다 다른 이유로 만든 것에 대해 굳이 불필요한 소모전을 벌일 필요가 없다. 이렇게, 저렇게 만들었다면 그거에 맞춰 구현을 하면 된다. 이런 구현 능력을 갖추는 게 더 우선이지 않을까? 시간이 지나면서 느끼는 것이 바로 이런 것들이다. 이론적인 정답만 좇는 것이 아닌 팀을 위한 답을 도출하는 것이 더 중요한 것 같다. 회사를 다니면서 내가 생각한 이상적인 모습들이 사라지고, 현실과 타협하다 보니 그런 것 같기도 하다. 코딩만이 아닌 여러 가지 상황을 고려하게 된다.
그렇다고 해서 무조건적으로 받아들여야 한다는 뜻은 아니다. 이런 내용을 아는 상태에서 받아들이는 것과, 내가 모르니까 그저 순응하는 것은 전혀 다른 이야기다. 또한, API 설계에 대해 컨벤션이 정해져 있지 않은 상태에서 새로운 프로젝트를 시작한다거나, 내가 팀을 리드하게 된다면 설득은 해볼 수 있다.
그런 상황에서 좋은 이정표가 될 수 있을만한 게 바로, 구글에서 만든 API 설계 가이드 문서이다.
The response should include the fully-populated resource, and must include any fields that were sent and included in the update mask unless they are input only (see AIP-203). - AIP 133, AIP 134
API 설계 가이드 문서에 따르면, Create / Update 시 응답에는 완전히 채워진 리소스를 포함해야 하며, 입력 전용이 아닌 경우, 업데이트 마스크에 보내고 포함된 모든 필드를 포함해야 한다.
결국 진리의 팀바팀, 케바케..라고는 하지만 얼마든지 개선의 여지는 있을 것이다.
여담으로, 글을 쓰기 위해 잠깐 공부해 봤는데 API 설계 시 고려해야 할 것들이 너무나 많은 것 같다. 어느 정도는 서로의 분야에 대해 아는 것이 당연히 좋겠지만, 각자의 포지션에서 서로의 전문성을 발휘하는 게 맞지 않을까. API 디자인은 백엔드 개발자가 하고, 프론트엔드 개발자가 검토를 같이 하는 게 맞지 않나 싶다.
https://onlydev.tistory.com/182
다음 내용이 궁금하다면?
이미 회원이신가요?
2023년 12월 20일 오후 3:07
저번 글과 이번 글 모두 인상 깊게 읽었습니다. 최근 CQRS 패턴에 대해서 알게 되어서 공부해보던 도중, 병연님의 리소스 관련 글이 생각나더군요. 해당 패턴은 DB CUD를 Command로, R은 Query로 분리하는 것이 규칙입니다. 특히 Command 관련 API는 성공 / 실패 만을 알려주는게 일반적이더군요. 서버도 Entity 데이터 변경에 대응하기 위한 방법인데, 병연님은 해당 패턴에 대해 어떻게 생각하시는지 궁금합니다 :)
@장성호 안녕하세요, 성호님! 좋은 말씀 감사드립니다. :) 저는 일단 CQRS 패턴이라는 것을 성호님 댓글에서 처음 알게 되었어요. 그래서 이렇다 할 의견을 낼 수준이 아니라고 생각해요. 사실 며칠 동안 시간 날 때마다 관련 문서도 읽어보고, 영상도 몇 개 봤는데 아직도 어렵네요 ㅎㅎ; 그래도 김영한님의 우아콘2020 영상을 보고나서, 아..CQRS는 이럴 때 쓰고 이런 장점이 있구나라는 것을 조금은 알게 된 것 같아요. (https://youtu.be/BnS6343GTkY?si=jStfg_6_Yb0eIYsf) 혹시 말씀하신 내용 중에 "Command 관련 API는 성공 / 실패 만을 알려주는게 일반적"이라고 하신 게 영상에서 나온 ZERO-PAYLOAD 부분과 연관이 있을까요? 그리고 성호님은 CQRS 패턴에 대해 어떻게 생각하시는지도 궁금합니다!
ZERO-PAYLOAD는 Event Queue를 사용할 때, 다음처럼 시스템을 구축하는 것으로 이해하고 있습니다. 1. 이벤트 생산자는 최소한의 데이터만 담은 이벤트를 발행한다. 2. 이벤트 소비자는 이벤트 수신 뒤, 필요한 데이터가 더 있다면 생산자의 시스템에 API 등으로 직접 받아간다. 병연님과 저의 이해가 같다면, 이것도 어느정도 연관이 있다고 생각합니다. 이벤트 생산자 입장에선 데이터 생산 API 호출한 프론트나, 추가로 데이터를 원하는 이벤트 소비자 둘 다 클라이언트니까요. 클라이언트 입장에선 최소한의 데이터만 있는 이벤트랑, 성공 / 실패 응답만 있는 데이터가 많이 비슷할 거 같아요. 아까 1번에서 “최소한의 데이터”라는 영역이 애매한데, 이건 팀 내에서 생산성을 고려해, 알맞게 정의해야한다고 생각해요. 같은 의미로 CQRS 패턴도 성공 / 실패 응답이 클라이언트의 생산성을 떨어트린다면, 생산된 데이터는 응답해주는 게 맞다고 생각합니다. ID 값이나 이미지 경로 같은 건 서버가 꼭 응답해줘야 하니까요. 보완한다면 예를 들어 1. 데이터 저장 후, 클라이언트가 GET 요청 보내기 2. 데이터 저장 후, 서버가 바로 읽어서 데이터 응답 3. BFF 서버를 만들어 1번 과정을 서버 내로 추상화 4. GraphQL로 클라이언트 입장에서 1번 과정을 한 번의 호출로 처리 이런 방식들이 있을 거 같아요!
@장성호 아..이벤트 큐 방식으로 구축한다면 마지막에 받은 이벤트가 최신 정보가 되는 것이니까, 병렬적으로 오는 요청에 대한 복잡함이 줄어들겠군요. 그리고 소비자가 이벤트를 수신한 후, 그에 맞는 세부적이고 잘 정의된 API를 호출하여 해당 데이터에 대한 최신 정보를 업데이트 하는 것이, 성호님이 설명하신 보완방법과 맥락이 비슷하다고 이해를 했습니다. 맞을까요?
@김병연(Vintz) 네 맞아요!
@장성호 그렇군요! ㅎㅎ 덕분에 배웠습니다. 감사해요 성호님. :)
@김병연(Vintz) 다양한 의견 나눠주셔서 감사합니다😊 저도 많이 배웠어요!!