CAP for Node

[CAP for Node] OData V4 쿼리 심화 — $filter, $expand, $orderby 실전 활용

▶ YouTube에서 보기

[CAP for Node] OData V4 쿼리 심화 — $filter, $expand, $orderby 실전 활용

Moderator · 2026. 4. 24. · 조회 7

[CAP for Node] OData V4 쿼리 심화 — $filter, $expand, $orderby 실전 활용

Moderator · 2026. 4. 24. · 조회 7

[CAP for Node] OData V4 쿼리 심화 — $filter, $expand, $orderby 실전 활용

개요

SAP CAP(Cloud Application Programming) Node.js에서 OData V4 쿼리 옵션은 클라이언트가 서버로부터 필요한 데이터만 정확히 가져오는 핵심 메커니즘입니다. $filter로 조건 필터링, $expand로 연관 엔티티 동시 조회, $orderby로 정렬을 수행하며, CAP은 이를 CDS 쿼리(CQN)로 자동 변환합니다. OData V2는 더 이상 권장되지 않으며(deprecated), V4가 CAP의 기본 프로토콜입니다.

이 글에서 다루는 것

핵심 개념

  • $filtereq, ne, gt, lt, ge, le 연산자와 and/or/not 논리 연산, contains(), startswith(), endswith() 함수를 지원합니다. 예: $filter=Country eq 'KR' and Price gt 100
  • $expand — Association으로 정의된 연관 엔티티를 한 번의 요청으로 가져옵니다. 중첩 필터도 가능합니다: $expand=Items($filter=Quantity gt 5;$orderby=Price desc)
  • $orderby + $top/$skip$orderby=CreatedAt desc&$top=20&$skip=40으로 서버 사이드 페이지네이션을 구현합니다. CAP은 자동으로 SQL LIMIT/OFFSET으로 변환합니다.
  • CQN 변환 — CAP 런타임은 OData 쿼리 파라미터를 CDS Query Notation(CQN)으로 변환하여 데이터베이스에 전달합니다. 커스텀 핸들러에서 req.query로 접근할 수 있습니다.

코드 예제

Books와 Authors 엔티티를 정의하고 OData V4 쿼리를 활용하는 예제입니다.

// db/schema.cds
namespace bookshop;

entity Books : cuid, managed {
  title    : String(200);
  price    : Decimal(10,2);
  currency : String(3);
  stock    : Integer;
  author   : Association to Authors;
  genre    : String(50);
}

entity Authors : cuid, managed {
  name    : String(100);
  country : String(2);
  books   : Composition of many Books on books.author = $self;
}
// srv/cat-service.js
const cds = require('@sap/cds');

module.exports = class CatalogService extends cds.ApplicationService {
  async init() {
    const { Books } = this.entities;

    // $filter 커스텀 처리 예제 — 외부 API 소비 시
    this.on('READ', 'Books', async (req) => {
      // req.query 에 CQN 형태로 변환된 쿼리가 들어옴
      // CAP이 자동 처리하지만, 커스텀 로직 추가 가능
      const query = req.query;

      // 예: stock이 0인 도서에 'Out of Stock' 표시
      const results = await cds.run(query);
      return results.map(b => ({
        ...b,
        availability: b.stock > 0 ? 'In Stock' : 'Out of Stock'
      }));
    });

    await super.init();
  }
};

클라이언트에서 호출하는 OData V4 쿼리 예시입니다.

-- 기본 필터링
GET /catalog/Books?$filter=genre eq 'Fiction' and price lt 30

-- 저자와 함께 확장 조회 + 중첩 필터
GET /catalog/Authors?$expand=books($filter=stock gt 0;$orderby=price asc;$top=5)

-- 페이지네이션
GET /catalog/Books?$orderby=createdAt desc&$top=20&$skip=40&$count=true

-- 함수 기반 필터 (부분 문자열 검색)
GET /catalog/Books?$filter=contains(title,'Cloud') or startswith(title,'SAP')

실무 팁

  • $count=true를 함께 사용하면 전체 건수를 응답 헤더에 포함시켜 UI 페이지네이션 구현이 편리합니다.
  • $expand 성능 — 깊은 중첩 확장(3단계 이상)은 JOIN이 많아져 성능이 저하됩니다. 필요한 필드만 $select와 함께 사용하세요.
  • 외부 REST API 소비 — CAP이 외부 비-OData API를 소비할 때는 $filter/$orderby가 자동 변환되지 않으므로, on('READ') 핸들러에서 req.query를 파싱하여 수동으로 매핑해야 합니다.

자세한 내용은 본문에서

더 읽어볼 자료


⚠️ 비공식 콘텐츠 안내

본 게시글은 btpstacks.com의 독립 학습 콘텐츠이며 SAP SE와 무관합니다. 공식 문서는 help.sap.com을 참고하세요.

SAP, ABAP, SAP BTP, SAPUI5, SAP Fiori는 독일 및 기타 국가에서 SAP SE의 상표 또는 등록상표입니다.

댓글 0

아직 댓글이 없습니다.