백엔드 API를 어떻게 설계하는지가 Next.js 프로젝트의 성패를 좌우하기도 하는데요.
결론부터 말씀드리면, Next.js와 가장 잘 맞는 백엔드 API는 바로 ‘세분화된(fine-grained)’ 단위로 설계된 API입니다.
잠깐 이 글의 주제를 명확히 할게요#
이 글에서 다루는 내용은 ‘Next.js가 호출할 백엔드 API의 설계’에 대한 이야기인데요.
‘Next.js의 라우트 핸들러(Route Handler)로 직접 API를 만드는 방법’에 대한 내용이 아니니 혼동하지 않으시길 바랍니다.
API 설계의 오랜 딜레마#
요즘 백엔드 API 개발에서 가장 널리 쓰이는 방식은 단연 ‘REST API’거든요.
REST API 설계의 기본 원칙은 리소스를 가능한 한 작고 세분화된 단위로 나누는 것입니다.
하지만 이렇게 잘게 쪼개면, API를 사용하는 쪽에서는 통신 횟수가 늘어날 수밖에 없는데요.
이걸 피하기 위해 일부러 더 큰, ‘굵은 단위(coarse-grained)‘로 API를 설계하는 경우가 많았습니다.
세분화된 API는 통신 횟수가 많아져서 ‘채티 API(Chatty API)’, 즉 수다스러운 API라고 불리기도 하고, 반대로 너무 굵은 단위의 API는 범용성이 떨어져서 ‘갓 API(God API)‘라고 불리며 둘 다 안티패턴으로 여겨지기도 하는데요.
사실 이건 어느 한쪽이 무조건 나쁘다기보다는, 상황에 따라 장단점이 명확한 트레이드오프 관계라고 보는 것이 맞습니다.
세분화된 API는 설계 관점에서는 명확하고 좋지만, 느린 네트워크 환경에서는 성능에 불리하고, 굵은 단위의 API는 그 반대의 특징을 가집니다.
과거에는 왜 큰 단위의 API가 많았을까#
‘페이지 라우터(Pages Router)’ 시절을 포함해 앱 라우터가 등장하기 전의 리액트 애플리케이션에서는, 백엔드 API가 특정 ‘페이지’와 너무 강하게 결합되는 경우가 많았거든요.
클라이언트에서 직접 데이터를 가져올 때는 통신 횟수 자체가 성능에 치명적이었기 때문에, 페이지마다 딱 한 번의 통신으로 모든 것을 끝내려는 경향이 강했습니다.
심지어 getServerSideProps()를 사용해 서버 간 통신을 하더라도, 이 함수 자체가 ‘페이지’ 단위로 정의되었기 때문에 자연스럽게 API도 페이지에 필요한 모든 정보를 담은 굵은 단위로 설계되곤 했습니다.
앱 라우터 시대의 새로운 기준#
하지만 앱 라우터 시대에는 이야기가 완전히 달라지는데요.
서버 컴포넌트 덕분에 데이터 페칭을 컴포넌트 단위로 자유롭게 배치하고 분리하는 것이 아주 쉬워졌습니다.
바로 이 특징 때문에, 앱 라우터는 세분화된 REST API와 정말 최고의 궁합을 자랑하는데요.
이건 백엔드 개발팀 입장에서도 큰 장점입니다.
세분화된 REST API는 그 자체로 구현이 더 단순하고 명확해지는 경우가 많거든요.
결국 프론트엔드와 백엔드 모두에게 이득이 되는 설계입니다.
RSC와 GraphQL의 평행 이론#
사실 이런 세분화된 API 설계는 RSC에서 처음 등장한 개념은 아닌데요.
과거부터 ‘그래프큐엘(GraphQL)‘을 BFF로 사용할 때, 그 뒤에 있는 백엔드 API는 세분화된 형태로 만드는 것이 선호되었습니다.
바로 이 지점에서 RSC와 GraphQL의 공통된 철학을 엿볼 수 있는데요.
이전 글에서도 언급했듯이, RSC를 처음 제안한 ‘조 사보나(Joe Savona)‘는 그래프큐엘 전문가였습니다.
이런 배경을 생각해보면 RSC가 그래프큐엘의 정신을 이어받은 후계자라는 말이 더 깊이 와닿으실 겁니다.
현실적인 고려사항들#
백엔드와의 통신 횟수#
아무리 서버 간 통신이 빠르다고 해도, 통신 횟수가 너무 많아지면 당연히 성능에 영향을 줄 수 있거든요.
이럴 때는 앞서 다룬 ‘병렬 데이터 페칭’, ‘데이터로더(DataLoader)’, 그리고 Next.js의 ‘데이터 캐시(Data Cache)’ 같은 기술들을 적극적으로 활용해서 통신 빈도와 성능을 최적화하는 것이 중요합니다.
백엔드 개발팀과의 협업#
백엔드 API는 여러 시스템에서 함께 사용할 수 있기 때문에, Next.js에 편하다는 이유만으로 우리 마음대로 결정할 수 있는 문제는 아니거든요.
백엔드 개발팀이 가진 경험이나 그들만의 철학도 분명히 존재합니다.
하지만 세분화된 API가 프론트엔드뿐만 아니라 백엔드 개발팀에게도 설계적인 이점을 준다는 사실을 논리적으로 설명하고, Next.js의 동작 방식을 공유하며 이해를 구하는 노력이 무엇보다 중요합니다.