노트

중첩 리소스 엔드포인트

Nested Resource

백엔드#http#architecture · 연결된 개념 2개

쉽게 말하면

중첩 리소스는 '101동 1203호'처럼 큰 단위 아래에 작은 단위를 이어 붙인 주소예요. '5번 고객의 주문들'처럼 무엇이 누구와 관련된 것인지 주소만 보고 알 수 있죠.

비유의 한계 아파트 호수는 동에 붙박이지만, 주문은 혼자서도 '99번 주문'으로 찾을 수 있어요. 경로는 관계를 보여 줄 뿐 DB의 부모·자식 구조를 따를 필요가 없고, 너무 깊게 이으면 관리가 어려워져요.

/customers/5/orders처럼 한 리소스 아래에 그와 관련된 리소스 컬렉션을 두는 URI(Uniform Resource Identifier) 설계를 중첩 리소스(nested resource)라고 부른다. 그런 경로를 가진 엔드포인트를 nested endpoint, 아래쪽 리소스를 sub-resource라고도 한다. 표준 용어는 아니고 REST(Representational State Transfer) API 설계에서 관례로 쓰는 이름이다. URI의 경로(path)는 보통 계층 형태로 리소스를 식별하고, 중첩 리소스는 그 계층으로 리소스 사이의 관계를 표현한다.

GET /customers          고객 컬렉션
GET /customers/5        고객 5 (개별 리소스)
GET /customers/5/orders 고객 5의 주문 컬렉션 (중첩 리소스)
GET /orders/99          주문 99 자체

관계를 보여 줄 뿐, DB 구조가 아니다

  • 경로는 "고객 5와 관련된 주문"이라는 관계를 말한다. 저장소에서 주문이 고객 테이블 밑에 있다는 뜻이 아니다
  • 반대로 DB의 내부 구조를 그대로 URI로 드러내지 않는다. 테이블마다 컬렉션을 만들면 구현이 클라이언트에 새고 공격 면도 넓어진다
  • 중첩 리소스가 독립 리소스이기도 하면 두 경로가 함께 있을 수 있다. /customers/5/orders는 고객과의 관계로 주문 목록에 접근하고, /orders/99는 주문 하나를 직접 가리킨다. 관계는 반대 방향(/orders/99/customer)으로도 표현할 수 있다

깊이는 컬렉션/항목/컬렉션까지

/customers/1/orders/99/products처럼 관계를 여러 단계 따라가는 URI는 유지하기 어렵고, 나중에 리소스 사이의 관계가 바뀌면 대응하기 어렵다. 마이크로소프트의 API 설계 가이드는 컬렉션/항목/컬렉션보다 복잡한 URI를 요구하지 말라고 권한다. 주문 99를 알고 있다면 /orders/99/products로 바로 가면 된다.

피할 것: /customers/1/orders/99/products
나눠서:  /customers/1/orders      → 고객 1의 주문 목록
        /orders/99/products      → 주문 99의 상품 목록

관계를 더 따라가야 하면 응답 본문에 관련 리소스의 링크를 넣는 방법(HATEOAS, Hypermedia as the Engine of Application State)도 있다. 한 번에 여러 단계의 관계를 가져와야 하는 화면이 많다면 GraphQL이 맞을 수 있다.

이름 짓기

구글 API 설계 가이드(AIP-122)는 리소스 이름을 publishers/123/books/les-miserables처럼 컬렉션 식별자와 리소스 ID가 번갈아 나오게 짓는다. 컬렉션 식별자는 복수형 명사를 쓴다. 스프링에서 이런 경로를 받는 방법은 스프링 REST 컨트롤러를 본다.

명세: RFC 3986 §3.3 — Path 출처: Microsoft Learn — Web API design best practices: Resource URI naming conventions · Google AIP-122 — Resource names

연결된 개념

이 노트를 가리키는 문서

뜻이 가까운 노트

  • loading 경계와 레이아웃 끌어올리기

    Next.js App Router에서 loading.tsx는 같은 세그먼트의 page와 그 아래(하위 layout 포함)를 suspense로 감싸지만, **같은 세그먼트의 layout은 감싸지 않는다**. 그래서 데이터를 기다릴 필요가 없는 공통 UI(탭바, 필터 헤더)를 page에서 layout으로 끌어올리면 스켈레톤에 덮이지 않고 처음부터 실제 모습으로 보인다.

  • 연결 리스트

    각 노드가 값과 다음 노드를 가리키는 포인터를 가지고 사슬처럼 이어진 자료구조. 리스트는 맨 앞(Head)과 맨 뒤(Tail), 길이 정도만 기억한다. 배열과 달리 인덱스가 없다.

  • NestJS

    NestJS는 TypeScript를 전제로 모듈·의존성 주입(Dependency Injection, DI)·데코레이터(decorator) 구조를 제공하는 Node.js 서버 프레임워크다. 2017년 Kamil Myśliwiec가 만들었고, 구조를 강제하는 방식 때문에 흔히 "Node.js의 Spring"이라 불린다.

  • Pages Router에서 App Router로

    App Router는 Next.js 13에서 도입된 app/ 디렉터리 기반 라우터로, 서버 컴포넌트·중첩 레이아웃(Nested Layouts)·스트리밍을 기본으로 한다. pages/ 기반의 Pages Router에서 옮길 때 바뀌는 생각을 정리한다.

  • 멀티 에이전트 토폴로지

    여러 LLM 에이전트를 어떤 모양으로 연결해 일을 나눌지 정하는 구조. 단일, 수퍼바이저, 파이프라인, 스웜으로 나뉘고, 대부분의 일은 단일 에이전트로 시작하는 편이 낫다.

보기 옵션