개발자

API가 제공하는 데이터의 범위를 어떻게 잡을지 고민입니다.

2024년 05월 01일조회 262

안녕하세요. 개인 프로젝트로 풀스택 웹 서비스를 여러 번 만들어보다가 생긴 의문입니다. 보통 저는 백엔드는 nestjs와 프론트엔드는 nextjs로 개발을 합니다. 프론트 쪽에서 react query를 사용하여 백엔드의 데이터를 fetch하여 사용하는데, 한 화면에 여러 데이터가 필요한 경우가 있습니다. 원래 백엔드 api를 짤 때 resource를 기준으로 잡았었는데 이렇게 하다보면 재사용 측면에서는 좋으나 위에서 말한 경우와 같이 한 화면에 여러 resource에 대한 데이터마다의 api를 호출하기 때문에 한 화면에서 여러 api 통신이 이루어지게 되어 cost가 있지 않을까 생각이 들었습니다. 1. 그래서 아예 한 화면에 쓰이는 데이터를 전부 serving하는 api 라우트 하나를 두면 해당 api 하나만 호출했을 때 한 번의 통신만으로 데이터를 가져오기 때문에 이 방식이 괜찮다고 생각이 들었는데 실제로 어떤 것이 더 좋은지 궁금합니다. 뭔가 감으로는 리소스별로 독립된 api를 여러개 호출하는 방식이 장점이 많은 것 같은데(querykey로 캐싱을 따로 할 수 있는 등) api 갯수가 1개랑 3개라고 하면 사용자마다 3배 많은 통신이 이루어지게 되어 이 부분이 조금 걸립니다. 2. 그리고 유저에 대한 데이터를 응답한다고 했을 때 해당 테이블에 join으로 엮을 수 있는 다른 모든 테이블도 같이 포함시키는 것이 좋은지, 아님 분리시켜서 user 테이블의 속성만 제공하는 api(/users)와 다른 테이블의 정보도 같이 포함하는 api(/users/courses)를 따로 구분하는 것이 좋은지 그 범위를 아예 모든 정보를 다 가져오는 것과 딱 필요한 정보만 제공하는 것 중 어느 방식이 어떤 측면을 가지고 있는지 궁금합니다.

이 질문이 도움이 되었나요?
'추천해요' 버튼을 누르면 좋은 질문이 더 많은 사람에게 노출될 수 있어요. '보충이 필요해요' 버튼을 누르면 질문자에게 질문 내용 보충을 요청하는 알림이 가요.

답변 2

행운아777님의 프로필 사진

--> 원래 백엔드 api를 짤 때 resource를 기준으로 잡았었는데 이렇게 하다보면 재사용 측면에서는 좋으나 위에서 말한 경우와 같이 한 화면에 여러 resource에 대한 데이터마다의 api를 호출하기 때문에 한 화면에서 여러 api 통신이 이루어지게 되어 cost가 있지 않을까 생각이 들었습니다. 위에 원 질문에서 복붙한 내용은 정확한 분석이 맞습니다. 또한 재사용은 현대적인 소프트웨어 개발에서 가장 중요한 요소 중 하나이기 때문에 최대한 재사용이 용이한 설계를 하는 것이 올바르다 할 수 있습니다. 그렇다면 api 통신이 여러번 발생해서 낭비되는 오버헤드는 어떻게 할 것인가? - 하는 질문이 남게되는데 이 것은 보통 서비스의 화면 구성에 최적화된 api를 추가로 개발하게 되는 이유가 되는 것입니다. api를 low level과 application level로 나눠서 아래와 같이 자사 서비스만을 위한 자체 api stack을 구성 하게 되는 것이죠. ---------------------------- 자사 응용 레벨 -> user, course, user-course, user-address, course-address, 등등 api ---------------------------- 자사 로우 레벨 -> user, course, address, auth, 등등 service ---------------------------- 진짜진짜 로우 레벨 의존성 -> next.js + 플라즈마 + mysql ---------------------------- 예를들어 유저 정보를 담당하는 user service, 강의 정보를 담당하는 course service, 주소록을 관리하는 address service, 등등 domain과 resource의 구조에 최적화된 low level api들을 만들고, 이 것들을 조합하여 화면구성에 최적화된 형태로 user api, course api, user-course api, user-address api, course-address api, 등등을 만드는 겁니다. (사용자의 프로필을 조작 하는 화면에서는 user api 호출, 사용자의 수강 내역을 조회하는 화면에서는 user 정보와 관련된 수강 내역을 같이 조회할 수 있는 user-course api 호출 하는 식으로) 소프트웨어가 이렇게 구성되었을 경우 만약 서비스가 "기능은 동일하지면 룩앤필을 멋지게 바꾸는 전면 개편"이 발생했을 때(실무에서 리브랜딩 등의 이유로 아주 빈번히 발생하는 전면개편 작업) low level api들은 변경될 일이 거의 없을 것이고 화면 구성과 직결되는 application level api들은 많은 부분 재작성되거나 버려지게 될 것입니다. 또한 low level api들은 서비스의 도메인과 더 강하게 결합 되어 있게 될 것이고, 때문에 회사의 업무 domain에 변화가 생겼을 경우 low level api만 변경해주면 application level에서는 변경 없이 기능을 유지하는 것이 가능할 것입니다. 그리고 이러한 api stacking은 보통 초기 단계에서는 쓸모/필요가 없고 서비스가 쫌 떠서 어느정도 사용자들을 확보해서 서버부하가 늘어나고 "** 화면 접속하는데 존나 느리다 니네 장난치냐"라는 항의가 막 늘어나고 예산 관련 부서에서 "서버 비용 이번 달에 ***만원 나왔는데 개발자 니네들 장난치냐? 이게 지금 우리 규모에 말이 된다고 생각하냐?" 뭐 이런 이야기들이 슬슬 나오기 시작할 때 유효한 것들입니다. 물론 미리미리 고민하고 대비를 해두면 무척 좋겠지요. 비슷한 맥락으로 두번째 질문에 대해서도 상황에 따라 다른 전략을 선택해야한다고 밖에는 대답드릴 수 없을 것 같습니다. 특히나 db에서 join하는 것과도 연관지어 질문하셨기 때문에 이런 답변을 드린 것인데, 웹기반 앱 또는 웹 api들의 성능 병목은 90%이상 관계형 db에서 발생합니다. 따라서 많은 경우 서버 부하나 성능에 문제가 생겼을 경우 db나 쿼리 튜닝을 하게 되됩니다. 이러한 맥락에서 두번째 질문의 예시를 그대로 갖고와 설명해보자면, 만약 "나의 수강 현황" 화면이 너무나 인기 있는 화면이어서 성능 문제가 발생하고 있다 - 라고 가정 한다면 맨 처음 화면을 랜더하기 위한 user+course api를 구성하고 db에 인덱스 등등도 잘 추가해주고 해서 user+course를 1방에 join 해서 갖고 와서 최대한 빨리 초기 화면을 렌더 해준 다음, course의 다음 페이지를 조회할 때는 course만 빠르게 조회해서 갖고 오는, 즉 서버 부하를 줄이기 위해 최적화된 api를 따로 만들어서 갖고오는 이런 복잡한 전략을 사용해야 할 수도 있을 것입니다. 그러나 반대로 서버의 cpu와 disk 사용률이 막 1% 근처로 팽팽 놀고 한달에 서버 비용도 얼마 안나오는 상황이라면 저런 정도의 복잡성에 구지 오버 엔지니어링 하지는 않을 것 같습니다.

강창룡님의 프로필 사진

강창룡

작성자

광운대학교 전자통신공학과2024년 05월 01일

와... 정말 감사합니다!! 이 부분에 대해 고민을 해보면서 사실 상황에 따라 사용하는 방식이 다를 것 같다고 어렴풋이 생각했었는데 엄청 자세하고 또 각 상황별로 설명해주셔서 엄청난 인사이트를 얻을 수 있었습니다...! 클라우드 서버를 빌려서 실제 서비스를 하려다 보니 api 호출 비용에 신경쓰고 있던 찰나였는데 덕분에 말씀해주신대로 고민해보고 수월하게 결정할 수 있을 것 같습니다!

행운아777님의 프로필 사진

아참 추가로 첨언 드리면, 이렇게 도메인과 화면 구성에 차이가 커서 필요 없는 데이터가 클라이언트로 전송되어서 트래픽이 낭비되거나, 또는 여러 백엔드 api를 조합해서 호출해야 되는 상황이 생기게 되고 이로부터 발생되는 예외처리의 어려움, 서버 부하, 등을 해소하고자 graphql을 사용하는 것 같습니다.

지금 가입하면 모든 질문의 답변을 볼 수 있어요!

현직자들의 명쾌한 답변을 얻을 수 있어요.

또는

이미 회원이신가요?

AI 답변
커리어리 AI 봇 프로필 이미지

커리어리 AI 봇

GPT가 달아주는 답변입니다.

2024년 05월 01일

이 질문에서는 기본적으로 API 설계에 대한 우려를 표현하고 있습니다. 여러 개의 리소스를 각각의 API로 분리하여 가져오는 것이 좋을지, 아니면 한 화면에 필요한 모든 데이터를 제공하는 하나의 API로 만드는 것이 좋을지에 대한 고민입니다. 1. 두 가지 접근법 모두 장단점이 있습니다. - '하나의 화면에 필요한 모든 데이터를 제공하는 API' 접근법은 네트워크 통신 회수를 줄일 수 있는 장점이 있습니다. 하지만 이 방식의 단점은 유연성과 재사용성 입니다. 한 화면에서만 필요한 데이터를 위해 대량의 데이터가 반환되면, 다른 화면에서 해당 API를 사용하기 어렵게 됩니다. - 반대로 '각 리소스마다 독립된 API 호출'하는 방식은 맞춤형 데이터 페치가 가능하고 캐싱 및 재사용 측면에서 이점이 있습니다. 그러나 이 경우 네트워크 호출 수가 많아져 비용 문제가 발생할 수 있습니다. 어떤 결정을 내릴 때는 프로젝트의 요구 사항과 성능, 유지보수성 등 여러 요인을 고려해야 합니다. 2. 이 질문은 '한 리소스에 대한 데이터를 반환할 때, 연관된 다른 리소스들을 포함시킬 것인지 아닐 것인지'에 대한 것입니다. - 이는 주로 당신의 API가 얼마나 많이 사용되는지, 해당 정보가 필요한 사용자가 얼마나 많은지에 따라 다릅니다. 너무 많은 불필요한 정보를 제공하는 것이 성능에 부정적인 영향을 줄 수 있습니다. 또한, 필요한 경우에만 데이터를 결합하는 방식이 보안 측면에서도 좋을 수 있습니다. - 반면에, 만약 특정 리소스와 연관된 모든 정보가 자주 필요하다면, 이것들을 한 번의 호출로 가져오는 것이 성능면에서 효과적일 수 있습니다. 결국 API 설계는 프로젝트의 요구와 사용자의 필요성에 따라 다르게 접근해야 하는 문제입니다. 각 상황과 요구 사항에 맞게 적절히 균형잡힌 솔루션을 찾아야 합니다.

목록으로

지금 가입하면 모든 질문의 답변을 볼 수 있어요!