Using Associations and Compositions
CAP에서 연관 관계와 구성 사용하기
CAP에서 연관 관계와 구성은 엔티티 간의 관계를 모델링하는 데 사용됩니다. 연관 관계는 독립적으로 존재할 수 있는 엔티티 간의 관계를 정의하며, 구성은 포함 관계를 나타내는 데 사용됩니다.
연관 관계
연관 관계는 두 가지로 나뉩니다:
- 관리형 연관 관계: 관리형 연관 관계는 자동으로 외래 키 필드와 조인 조건을 추가합니다. 이는ToOne 연관 관계에 적합하며, 모델의 간결성을 유지하는 데 유리합니다.
- 비관리형 연관 관계: 비관리형 연관 관계는 임의의 조인 조건을 명시적으로 지정할 수 있습니다. 이는 복잡한 관계를 모델링하는 데 유용합니다.
To-One 연관 관계
ToOne 연관 관계는 한 엔티티가 다른 엔티티와 하나의 관계를 가질 때 사용됩니다. 예를 들어, 책과 저자 간의 관계는 ToOne 연관 관계로 모델링할 수 있습니다.
entity Books {
key ID: Integer;
author: Association to Authors;
};
To-Many 연관 관계
ToMany 연관 관계는 한 엔티티가 여러 엔티티와 관계를 가질 때 사용됩니다. 예를 들어, 저자가 여러 책을 쓸 수 있는 관계는 ToMany 연관 관계로 모델링할 수 있습니다.
entity Authors {
key ID: Integer;
books: Association to many Books on books.author = $self;
};
Many-To-Many 연관 관계
CDS는 Many-To-Many 연관 관계를 직접 지원하지 않습니다. 대신, 두 개의 One-To-Many 연관 관계를 사용하여 중간 엔티티를 통해 연결해야 합니다.
entity Authors {
key ID: Integer;
books: Association to many BookAuthor on books.author = $self;
};
entity BookAuthor {
key book: Association to Books;
key author: Association to Authors;
};
구성
구성은 포함 관계를 나타내며, 주로 문서 구조를 모델링하는 데 사용됩니다. 예를 들어, 주문과 주문 항목 간의 관계는 구성으로 모델링할 수 있습니다.
entity Orders {
key ID: Integer;
items: Composition of many OrderItems on items.order = $self;
};
entity OrderItems {
key ID: Integer;
order: Association to Orders;
};
구성은 연관 관계와 유사하지만, 자식 엔티티가 부모 엔티티에 포함되어 독립적으로 존재할 수 없는 차이가 있습니다. 또한, 부모 엔티티가 삭제되면 자식 엔티티도 함께 삭제됩니다.
연관 관계 노출
연관 관계는 서비스 인터페이스에서 노출될 수 있습니다. 이는 뷰나 프로젝션의 선택 목록에 연관 관계를 추가하여 수행할 수 있으며, OData 서비스에서는 이를 탐색 속성으로 제공합니다.
CAP에서 연관 관계 사용하기
SQLite 데이터베이스 설정
- package.json 파일 열기:
- package.json 파일을 열어 SQLite 데이터베이스 설정을 확인합니다.
- 데이터베이스 URL 변경:
- URL 키의 값을 db.sqlite에서 memory로 변경하여 메모리 내 데이터베이스를 사용합니다.
도메인 모델에 연관 관계 추가
schema.cds 파일 열기:
db 폴더에서 schema.cds 파일을 엽니다.
ToOne 연관 관계 추가:
Books 엔티티에서 Authors 엔티티로의 관리형 ToOne 연관 관계를 추가합니다. 이는 author라는 이름의 연관 관계로 정의됩니다.
entity Books {
key ID: Integer;
author: Association to Authors;
};
이 연관 관계를 통해 Books 엔티티에서 관련된 Authors 엔티티로 탐색하여 저자의 이름과 같은 세부 정보를 가져올 수 있습니다.
ToMany 연관 관계 추가:
Authors 엔티티에서 Books 엔티티로의 ToMany 연관 관계를 추가합니다. 이는 books라는 이름의 연관 관계로 정의됩니다.
entity Authors {
key ID: Integer;
books: Association to many Books on books.author = $self;
};
이 연관 관계는 한 저자가 여러 책을 쓸 수 있음을 반영합니다.
초기 데이터 조정
- com.sap.learning-Books.csv 파일 열기:
- db/data 폴더에서 com.sap.learning-Books.csv 파일을 엽니다.
- 데이터 삭제 및 복사:
- 이전에 추가한 항목을 삭제하고, test/5_associations/data 폴더에서 준비된 데이터를 복사하여 붙여넣습니다. CDS는 자동으로 외래 키 필드 author_ID를 생성하므로, 초기 데이터를 이에 맞게 조정해야 합니다.
테스트
- 새 터미널 열기:
- 메뉴에서 Terminal > New Terminal을 선택하여 새로운 터미널을 엽니다.
- cds watch 실행:
- 터미널에서 cds watch 명령을 실행하여 HTTP 서버를 시작합니다.
- 서비스 테스트:
- test 폴더로 이동하여 5_associations 하위 폴더를 엽니다.
- admin-service-requests.http 파일을 선택합니다. 이 파일에는 새로 생성된 연관 관계를 테스트하기 위한 준비된 HTTP 요청이 포함되어 있습니다.
- Send Request를 선택하여 서비스 메타데이터 문서를 요청합니다. 이 문서에는 생성된 연관 관계에 해당하는 탐색 속성이 나열됩니다.
- 다음 요청으로 모든 책을 저자 정보와 함께 가져옵니다.
- 마지막 요청으로 모든 저자를 책 정보와 함께 가져옵니다.
이렇게 CAP에서 연관 관계를 사용하여 엔티티 간의 관계를 모델링하고 테스트하는 과정을 완료했습니다.
2. Incorporating Common Reuse Aspects
CDS Aspect
CDS Aspect는 기존 정의에 새로운 요소를 추가하거나 속성과 주석을 덮어쓰는 데 사용됩니다. 이는 모델링의 관심사를 분리하는 강력한 메커니즘을 제공하며, 모델과 정의를 별도의 파일로 나누어 서로 다른 수명 주기를 가질 수 있도록 합니다. 이는 여러 사람이 기여할 수 있는 유연한 개발 환경을 지원합니다.
CAP에서 Aspect 사용하기
CAP에서 Aspect는 기존 엔티티 정의에 새로운 요소를 추가하는 데 사용됩니다. 이 글에서는 extend 지시자를 사용하여 Aspect를 적용하는 방법에 대해 설명하겠습니다.
Extend 지시자
extend 지시자는 기존 엔티티에 새로운 필드를 추가하거나 기존 메타데이터를 수정하는 데 사용됩니다. 예를 들어, Authors 엔티티에 someAdditionalField라는 필드를 추가할 수 있습니다.
extend entity Authors with {
someAdditionalField: String;
};
이렇게 추가된 필드는 생성된 데이터베이스 테이블에도 반영됩니다.
명명된 Aspect
명명된 Aspect는 여러 대상을 동일한 확장으로 적용할 수 있는 방법입니다. 예를 들어, ManagedObject라는 Aspect를 정의하여 createdAt과 createdBy 필드를 추가할 수 있습니다.
aspect ManagedObject {
createdAt: Timestamp;
createdBy: User;
};
extend Books with ManagedObject;
extend Authors with ManagedObject;
이렇게 하면 Books와 Authors 엔티티 모두에 ManagedObject Aspect가 적용됩니다.
Include 문법
명명된 Aspect를 Include 문법으로 사용하여 여러 Aspect를 한 번에 적용할 수 있습니다.
extend entity Authors with ManagedObject, AnotherAspect;
이 문법은 여러 extend 문을 순차적으로 사용하는 것과 동일한 효과를 줍니다.
공통 재사용 Aspect
CAP는 @sap/cds/common 모델을 통해 공통적인 타입과 Aspect를 제공합니다. 이 모델을 사용하면 실제 비즈니스 애플리케이션에서 학습된 모범 사례를 활용할 수 있습니다.
cuid Aspect
cuid Aspect는 엔티티 정의에 표준적인 UUID 타입의 기본 키를 추가하는 편리한 방법입니다. CAP 런타임은 UUID 타입의 키 필드를 자동으로 생성된 UUID로 채웁니다.

managed Aspect
managed Aspect는 데이터 레코드의 생성자와 수정자를 추적하는 데 사용됩니다. 이 Aspect는 createdAt, createdBy, modifiedAt, modifiedBy 필드를 추가합니다.

using {
cuid,
managed
} from '@sap/cds/common';
entity Books : cuid, managed {
title : String(255);
author : Association to Authors;
genre : Genre;
publCountry : String(3);
stock : NoOfBooks;
price : Price;
isHardcover : Boolean;
}
이렇게 하면 Authors 엔티티에 cuid와 managed Aspect가 적용되어, 기본 키와 관리 필드가 추가됩니다.
3. Working with Localized Data, Code Lists and Common Reuse Types
지역화 데이터
CAP는 지역화된 데이터를 제공하기 위해 localized 수정자를 사용합니다. 이는 엔티티 요소에 번역된 텍스트가 필요한 경우에 사용됩니다.
지역화 데이터 선언
예를 들어, Books 엔티티의 title 요소를 지역화하려면 다음과 같이 선언할 수 있습니다:
entity Books {
key ID: UUID;
title: localized String(255);
};
이렇게 선언하면 CDS 컴파일러는 Books.texts라는 별도의 엔티티를 생성하여 번역된 텍스트를 저장합니다.
entity Books.texts {
key locale: sap.common.Locale;
key ID: UUID;
title: String(255);
};
지역화 데이터 제공
CAP의 서비스 런타임은 자동으로 사용자의 선호 언어로 데이터를 제공합니다. 예를 들어, 사용자가 독일어로 설정한 경우, sap-locale=de 파라미터를 사용하여 요청할 수 있습니다:
GET <your_service_url>/Books?sap-locale=de
또는 Accept-Language 헤더를 사용할 수도 있습니다:
GET <your_service_url>/Books
Accept-Language: de
초기 데이터 제공
지역화된 데이터를 제공하려면 두 개의 .csv 파일이 필요합니다:
- 기본 언어 데이터 파일: 예를 들어, com.sap.learning-Books.csv 파일에는 기본 언어(예: 영어)로 된 데이터가 포함됩니다.
- 번역 데이터 파일: 예를 들어, com.sap.learning-Books.texts.csv 파일에는 다른 언어(예: 독일어)로 번역된 데이터가 포함됩니다1

코드 목록
CAP는 코드 목록을 제공하여 번역 가능한 값 목록을 표준화된 방식으로 제공합니다.
코드 목록의 목적
CAP에서 코드 목록은 제어된 값 목록을 관리하는 데 사용됩니다. 이는 고정된 값 집합을 표준화된 방식으로 정의하는 데 도움을 주며, 데이터 무결성을 보장합니다.
코드 목록의 이점
- 데이터 무결성: 코드 목록은 특정 필드에 입력할 수 있는 값을 제한하여 잘못된 데이터 입력으로 인한 오류를 방지합니다.
- 다국어 지원: 코드 목록은 코드 설명을 여러 언어로 유지할 수 있어 다국어 애플리케이션에 적합합니다.
- SAP Fiori UI 자동 생성: 코드 목록은 SAP Fiori UI에서 값 도움말을 자동으로 생성할 수 있으며, 이는 프론트엔드 개발의 노력을 줄이는 데 기여합니다.
sap.common.CodeList Aspect
sap.common.CodeList Aspect는 코드 목록의 기본 정의를 제공하며, @sap/cds/common 모델에 포함되어 있습니다. 이 Aspect는 name과 descr 요소를 정의하며, 이들은 지역화된 텍스트를 지원합니다.
aspect sap.common.CodeList {
name: localized String(255);
descr: localized String(1000);
};
사용자 정의 코드 목록 생성
사용자 정의 코드 목록을 생성하려면 sap.common.CodeList Aspect를 사용하여 엔티티를 확장할 수 있습니다. 예를 들어, Epochs 엔티티를 다음과 같이 정의할 수 있습니다:
using {
cuid,
managed,
sap.common.CodeList
} from '@sap/cds/common';
entity Epochs : CodeList{
key ID : Integer;
}
이렇게 하면 CDS 컴파일러는 Epochs.texts 엔티티를 생성하여 번역된 텍스트를 저장합니다.
entity Epochs.texts {
key locale: sap.common.Locale;
key ID: Integer;
name: String(255);
descr: String(1000);
};
공통 재사용 타입
CAP는 @sap/cds/common 모델을 통해 공통적인 타입과 Aspect를 제공합니다. 이 중에서 Country와 Currency 타입을 사용하는 방법에 대해 설명하겠습니다.
Country 타입
Country 타입은 sap.common.Countries 코드 목록에 대한 관리형 To-One 연관 관계를 정의합니다. 이 코드 목록은 ISO 3166-1 두 자리 알파 코드를 기본 키로 사용합니다.
entity sap.common.Countries {
key code: String(3);
name: localized String(255);
descr: localized String(1000);
};
Currency 타입
Currency 타입은 sap.common.Currencies 코드 목록에 대한 관리형 To-One 연관 관계를 정의합니다. 이 코드 목록은 ISO 4217 세 자리 알파 코드를 기본 키로 사용합니다.
entity sap.common.Currencies {
key code: String(3);
symbol: String(5);
minorUnit: Int16;
name: localized String(255);
descr: localized String(1000);
};
코드 목록 및 공통 타입 사용
코드 목록과 공통 타입을 사용하려면 다음과 같이 엔티티에 적용할 수 있습니다:
using { Country, Currency } from '@sap/cds/common';
entity Books {
key ID: UUID;
publCountry: Country;
price: {
amount: Decimal(10, 2);
currency: Currency;
};
};
이렇게 하면 publCountry와 price_currency가 탐색 속성으로 제공되며, 코드 목록 엔티티가 자동으로 노출됩니다.
퀴즈
이번에는 CAP와 CDS 관련된 다양한 문제를 풀어보겠습니다.
1. CDS에서 직접 지원하는 연관 관계 유형은 무엇인가요?
보기:
- one-to-many association
- many-to-one association
- one-to-one association
- many-to-many association
정답:
- one-to-many association
- many-to-one association
- one-to-one association
설명: CDS는 one-to-many, many-to-one, one-to-one 연관 관계를 직접 지원하지만, many-to-many 연관 관계는 직접 지원하지 않습니다.
2. 번역된 텍스트가 필요한 엔티티 요소를 선언할 때 사용하는 수정자는 무엇인가요?
보기:
- translated
- internationalized
- localized
- globalized
정답: localized
설명: 번역된 텍스트가 필요한 엔티티 요소를 선언할 때는 localized 수정자를 사용합니다.
3. Authors 엔티티에서 epoch라는 요소를 통해 Epochs 코드 목록을 사용하려면 어떻게 정의해야 하나요?
보기:
- epoch : Epochs;
- epoch : Association to many Epochs on epoch.author = $self;
- epoch : CodeList of Epochs;
- epoch : Association to Epochs;
정답: epoch : Association to Epochs;
설명: 코드 목록을 사용하려면 관리형 To-One 연관 관계를 정의해야 합니다. 이는 epoch: Association to Epochs;와 같이 정의할 수 있습니다.
4. CDS에서 공통 타입과 Aspect를 제공하는 모델의 이름은 무엇인가요?
보기:
- @common/cds/sap
- @sap/common/cds
- @cds/common/sap
- @common/sap/cds
- @cds/sap/common
- @sap/cds/common
정답: @sap/cds/common
설명: @sap/cds/common 모델은 CDS에서 공통 타입과 Aspect를 제공하여 모델의 간결성과 상호 운용성을 높이는 데 도움을 줍니다.
5. 지역화된 데이터의 독일어 버전을 요청하려면 어떤 방법을 사용할 수 있나요?
보기:
- 요청 헤더 User-Agent: de
- 쿼리 문자열 sap-locale=de
- 요청 헤더 Accept: de
- 쿼리 문자열 language=de
- 요청 헤더 Accept-Language: de
- 쿼리 문자열 ui-language=de
정답:
- 쿼리 문자열 sap-locale=de
- 요청 헤더 Accept-Language: de
설명: 지역화된 데이터를 요청할 때는 쿼리 문자열 sap-locale=de 또는 요청 헤더 Accept-Language: de를 사용할 수 있습니다.
6. sap.common.Currencies 엔티티에 정의된 요소는 무엇인가요?
보기:
- ID
- code
- unit
- symbol
- minorUnit
정답:
- code
- symbol
- minorUnit
설명: sap.common.Currencies 엔티티는 code, symbol, minorUnit 요소를 정의합니다.
7. CDS에서 핵심 도메인 엔티티에 보조적인 측면을 추가하는 데 사용되는 지시자는 무엇인가요?
보기:
- enhance 지시자
- append 지시자
- extend 지시자
- expand 지시자
- annotate 지시자
정답:
- extend 지시자
- annotate 지시자
설명: CDS에서 핵심 도메인 엔티티에 보조적인 측면을 추가하는 데는 extend와 annotate 지시자가 사용됩니다.
8. 서비스 인터페이스에서 연관 관계를 노출하는 것에 대한 다음 중 어떤 문장이 맞나요?
보기:
- 구성은 프로젝션에서 노출될 수 없습니다.
- 연관 관계는 프로젝션의 선택 목록에 일반 요소처럼 추가될 수 있습니다.
- 관련 엔티티의 연관 관계는 프로젝션에서 자동으로 리디렉션됩니다.
- OData 서비스에서는 발행된 연관 관계가 탐색 속성으로 제공됩니다.
정답:
- 연관 관계는 프로젝션의 선택 목록에 일반 요소처럼 추가될 수 있습니다.
- 관련 엔티티의 연관 관계는 프로젝션에서 자동으로 리디렉션됩니다.
설명: 연관 관계는 프로젝션의 선택 목록에 일반 요소처럼 추가될 수 있으며, 관련 엔티티의 연관 관계는 프로젝션에서 자동으로 리디렉션됩니다. OData 서비스에서는 발행된 연관 관계가 탐색 속성으로 제공됩니다.
9. sap.common.CodeList Aspect에 정의된 요소는 무엇인가요?
보기:
- name
- ID
- locale
- descr
정답:
- name
- descr
설명: CodeList Aspect는 name과 descr 요소를 정의하며, 이는 지역화된 텍스트를 지원합니다.
10. Books 엔티티의 publCountry 요소를 sap.common.Countries 코드 목록과 연결하려면 어떻게 정의해야 하나요?
보기:
- publCountry : Country;
- publCountry : Countries;
- publCountry : Association to Country;
- publCountry : Association to Countries;
정답:
- publCountry : Country;
- publCountry : Association to Countries;
설명: sap.common.Countries 코드 목록과 연결하려면 Country 타입을 사용하여 publCountry 요소를 정의하거나, Countries 엔티티와의 관리형 To-One 연관 관계를 정의할 수 있습니다. 이는 publCountry: Country; 또는 publCountry: Association to Countries;와 같이 정의할 수 있으며, 이는 간접적으로 Countries 코드 목록을 참조합니다. 직접적으로 코드 목록 엔티티를 참조하는 경우는 드물며, 대신 재사용 타입 Country를 사용하는 것이 일반적입니다.