포스트

Data Definition

Data Definition

1. Annotation

select from 계층 (Interface / Root View)

@AbapCatalog.viewEnhancementCategory

  • 의미: 다른 개발자가 EXTEND VIEW ENTITY 구문을 사용하여 이 CDS 뷰에 필드를 추가하는 등의 구조 확장을 허용할지 정의합니다.
  • 옵션별 상세 설명:
  • [#NONE]: 확장 절대 불가. 내부 구조가 복잡하여 임의로 필드가 추가되면 쿼리 성능이 깨지거나 로직이 꼬일 위험이 있는 중요 인터페이스 뷰에 적용합니다.
  • [#PROJECTION_LIST]: 조회 필드(Select List) 확장만 허용. 가장 일반적으로 사용되며, 기본 키(Key)나 구조 자체를 바꾸지 않고 단순 조회용 필드만 맨 끝에 덧붙일 수 있게 합니다.
  • [#UNION]: Union 구조 확장 허용. UNION 구문이 들어간 복잡한 CDS 뷰에서 각 쿼리 블록의 필드 리스트를 동시에 확장할 수 있도록 허용합니다.
  • [#PRIVILEGED_ONLY]: 특수 권한 확장만 허용. SAP 시스템이 제공하는 안전한 전용 패키지나 특수 경로를 통해서만 확장이 가능하도록 제한합니다.

    @AccessControl.authorizationCheck

  • 의미: 데이터 조회 시 DCL(Data Control Language) 파일에 정의된 유저별/행별 접근 권한 오브젝트를 자동으로 체크할지 결정합니다.
  • 옵션별 상세 설명:
  • #NOT_REQUIRED: 권한 체크 생략. 권한 검사가 필요 없는 단순 마스터 코드성 데이터(예: 국가 코드, 통화 코드)를 조회하거나, 이미 백엔드 ABAP 프로그램 로직에서 권한 제어를 별도로 처리할 때 성능 최적화를 위해 사용합니다.
  • #CHECK: 무조건 권한 체크. 급여 데이터, 매출 실적, 고객 개인정보 등 보안이 극도로 중요한 비즈니스 트랜잭션 데이터 레이어에 적용합니다. 대응하는 DCL 파일이 없으면 경고나 에러가 발생할 수 있습니다.
  • #PRIVILEGED_ONLY: 특수 경로만 허용. 일반적인 쿼리 조회가 아닌, 특정 권한이 부여된 클래스나 시스템 내부 프로세스를 통해서만 데이터 접근을 허용하고자 할 때 사용합니다.

    @EndUserText.label

  • 의미: Eclipse ADT, SE11 화면 등 시스템 전반에서 이 CDS 뷰를 식별할 때 보여주는 대표 이름(Description Text)입니다.
  • 사용 기준: 개발하는 모든 CDS 뷰에 무조건 필수적으로 작성해야 하며, 동료 개발자가 이 뷰의 비즈니스 목적을 바로 이해할 수 있도록 명확하게 작성합니다. (최대 60자)

    @Metadata.ignorePropagatedAnnotations

  • 의미: 이 CDS 뷰가 참조하는 하위 물리 테이블이나 데이터 엘리먼트(Data Element)에 걸려있는 메타데이터 어노테이션 속성들을 상속받을지 차단할지 제어합니다.
  • 옵션별 상세 설명:
  • true: 상속 차단 및 현재 뷰의 설정만 활성화. 하위 객체들의 복잡한 어노테이션이 섞여 들어와 원치 않는 사이드 이펙트가 발생하거나, 쿼리 분석 및 활성화 속도(Activation Performance)가 느려지는 것을 방지합니다. 최신 CDS View Entity 설계 시 무조건 **true로 설정하는 것이 글로벌 표준 규격**입니다.
  • false: 상속 허용. 하위 구조나 엘리먼트에 이미 정의되어 있는 UI 속성, 검색 속성, 레이블 정보 등을 그대로 물려받아 재사용하고 싶을 때 제한적으로 사용합니다.

as projection on 계층 (Projection View)

@Metadata.allowExtensions

  • 의미: UI 화면 배치 설정을 담은 별도의 메타데이터 확장 파일(Metadata Extension, .ddlx)을 분리하여 작성할 수 있도록 허용할지 여부입니다.
  • 옵션별 상세 설명:
  • true: UI 파일 분리 허용. @UI.lineItem이나 @UI.selectionField 같은 Fiori Elements 전용 화면 배치 어노테이션들을 CDS 본문이 아닌 별도 파일로 쪼갤 수 있게 합니다. 코드가 깔끔해지므로 실무 프로젝션 뷰에서는 무조건 **true로 설정**합니다.
  • false: UI 파일 분리 불허. 모든 UI 관련 어노테이션을 CDS 뷰 본문 내에 필드와 함께 빽빽하게 적어야 합니다. 유지보수성이 떨어지므로 권장하지 않습니다.

    @Search.searchable

  • 의미: 최종 Fiori Elements 화면의 우측 상단에 전체 텍스트를 검색할 수 있는 전역 검색창(Global Search Bar)을 활성화할지 여부입니다.
  • 옵션별 상세 설명:
  • true: 검색 기능 활성화. 이 설정을 켜고 본문 필드 중 원하는 컬럼에 @Search.defaultSearchElement: true를 붙여주면, 사용자가 해당 키워드로 전체 데이터를 검색할 수 있게 됩니다.
  • false: 검색 기능 비활성화. 화면 상단에 전역 검색 필드를 노출하지 않습니다.

    @ObjectModel.semanticKey

  • 의미: 기술적인 Key(예: UUID 등) 외에, 현업 사용자가 화면에서 인지하는 비즈니스 관점의 실질적인 유니크 키(얼굴 역할 필드)가 무엇인지 정의합니다.
  • 구문 형태: ['CarrierId', 'ConnectionId'] 형태로 대괄호 안에 필드명을 선언합니다. Fiori 화면 이동(Navigation) 시 타이틀이나 오브젝트 페이지의 헤더 영역에 해당 값이 대표로 노출됩니다.

    @AccessControl.authorizationCheck (프로젝션 레이어 기준)

  • 의미: 백엔드(Root View) 단계와 별개로, 최종 UI 화면으로 넘어가는 최종 길목에서 사용자의 권한을 한 번 더 검사할지 결정합니다.
  • 옵션별 상세 설명:
  • #CHECK: 화면 진입 시 최종 권한 체크. 백엔드 레이어에서는 개발 편의나 데이터 가공을 위해 #NOT_REQUIRED로 풀어두었더라도, 최종 사용자 화면에 뿌려줄 때만큼은 로그인한 유저의 소속 부서나 플랜트 권한에 맞춰 데이터를 필터링해야 할 때 주로 이 값을 선택합니다.
  • #NOT_REQUIRED: 프로젝션 단계에서도 별도의 DCL 권한 검사 없이 백엔드가 넘겨준 데이터를 그대로 화면에 바인딩합니다.

    2. Interface View 정의

  • 데이터베이스에 존재하는 원시 데이터를 가장 먼저 읽어와서,
    비즈니스 용어에 맞게 필드명을 매핑(Alias)해주는 가공되지 않은 순수 데이터 레이어입니다.
  • as select from 뒤에 올 수 있는 것:**
  • 물리 테이블: 데이터가 실제로 저장된 DB 테이블
    (예: SAP 스탠다드 테이블 /dmo/flight, CBO 투명 테이블 ztwbs_task2)
  • 스탠다드 뷰 / 타 CDS 뷰: SAP가 기존에 만들어 둔 표준 CDS 뷰나
    다른 개발자가 가공해 놓은 인터페이스 뷰도 가져와서 재사용 가능 ```bash define view entity ZI_LDG_FLIGHT as select from /dmo/flight { key carrier_id as CarrierId, key connection_id as ConnectionId, key flight_date as FlightDate, @Semantics.amount.currencyCode: ‘CurrencyCode’ price as Price, currency_code as CurrencyCode, plane_type_id as PlaneTypeId, seats_max as SeatsMax, seats_occupied as SeatsOccupied }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
## 3. Root View 정의
>
- 인터페이스 뷰(`ZI_LDG_FLIGHT`)를 소스로 지정하여 `select`하는 최상위 뷰입니다.
- **핵심 역할:** RAP(RESTful ABAP Programming) 프레임워크에서 하나의 비즈니스 오브젝트<br>(BO, 예: 한 장의 전표, 하나의 프로젝트) 구조를 잡을 때 <br>"내가 이 데이터 구조의 대장(최상위 노드)이다"라고 시스템에 선언하는 뷰. <br>이 루트 뷰를 중심으로 하위에 자식(Child) 뷰들이 구성(Composition)
```bash
define root view entity ZR_LDG_FLIGHT as select from ZI_LDG_FLIGHT
{
    key CarrierId,
    key ConnectionId,
    key FlightDate,
    @Semantics.amount.currencyCode: 'CurrencyCode'
    Price,
    CurrencyCode,
    PlaneTypeId,
    SeatsMax,
    SeatsOccupied,
    'https://example.com/Upload_Portal/it/Logo/COMPANY_LOGO.png' as FixedImageUrl
    //상수값도 가능(Y,N 테이블등 콤보박스 생성시에 사용)
}

4. Projection View 정의

  • 핵심 역할: Root View를 그대로 가져와서 “이 데이터 중 화면(프론트엔드)에 어떤 필드만 보여주고 어떤 기능을 허용할 것인가”를 결정하는 레이어입니다.
  • 주요 특징: * 데이터를 새로 select하거나 조인 등 가공하지 않음.
  • 오직 Fiori Elements 화면 연동을 위한 서비스 계약(provider contract)을 체결하고,
    UI 전용 어노테이션(@UI.lineItem, @UI.selectionField)을 붙여서 화면 레이아웃 설정
  • 하나의 Root View를 기반으로 일반 사용자용 프로젝션 뷰, 관리자용 프로젝션 뷰, 모바일 앱용 프로젝션 뷰 등 화면 목적에 따라 여러 개로 쪼개어 만들 수 있는 포장지 역할 ```bash define root view entity ZP_LDG_FLIGHT provider contract transactional_query as projection on ZR_LDG_FLIGHT {
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
// [필터바 추가] position 번호 순서대로 화면 왼쪽부터 배치됩니다.
// [테이블 컬럼 추가] lineItem이 붙은 필드만 Fiori 테이블에 컬럼으로 나타납니다.
@UI:{
    lineItem: [{position: 10, label: 'Airline ID'}]
    ,selectionField: [{ position: 10}]
    ,identification: [{ position: 10, label: 'Airline ID' }]
}
key CarrierId,

@UI.lineItem: [{ position: 20, label: 'Connection ID' }]
key ConnectionId,

@UI.selectionField: [{ position: 20 }] // 날짜로도 검색할 수 있게 필터바 배치
@UI.lineItem: [{ position: 30, label: 'Flight Date' }]
key FlightDate,

@Semantics.amount.currencyCode: 'CurrencyCode'
@UI.lineItem: [{ position: 40, label: 'Price' }]
Price,

CurrencyCode,

@UI.lineItem: [{ position: 50, label: 'Plane Type' }]
PlaneTypeId,

@UI.lineItem: [{ position: 60, label: 'Max Seats' }]
SeatsMax,

@UI.lineItem: [{ position: 70, label: 'Occupied Seats' }]
SeatsOccupied } ``` ### Define내 Annotation 정리 \[메인 페이지 - Report Page\] - **`@UI.selectionField`**: 화면 상단 **검색 필터 영역**에 입력 창을 띄우는 속성 - **`@UI.lineItem`**: 화면 중앙 **데이터 그리드 테이블**에 컬럼을 생성하는 속성 - **`position: 10, 20, 30...`**: 숫자가 작을수록 **왼쪽(테이블)** 또는 앞쪽(필터바)에 우선 배치됨 (보통 10 단위로 설계하여 향후 유지보수 시 사이에 필드를 끼워 넣을 수 있게 함) - **`label`** : **라벨 지정 - **`@UI.identification`**: 로우 클릭 시 진입하는 상세 페이지(Object Page)의 기본 정보 탭에 값 - **`@UI.hidden`** : **컬럼 목록에는 나오지 않게 하되, 상세 페이지나 내부 로직에서는 쓰고 싶을 때 사용<br>**`@UI.lineItem`** 을 적지 않아도 동일 \[상세 페이지 - Object Page\] - **`@UI.facet`** ** ```bash @UI.facet: [
/* --------------------------------------------------
   [탭 1] 부모 바구니: 비행기 상세 정보 (위치 10)
   -------------------------------------------------- */
{
  id:              'GeneralInfo',
  type:            #COLLECTION,
  label:           '비행기 상세 정보',
  position:        10
},
{
  id:              'FlightDetail',
  type:            #IDENTIFICATION_REFERENCE,
  label:           '기본 인포',
  parentId:        'GeneralInfo',
  position:        10
},

/* --------------------------------------------------
   [탭 2] 부모 바구니: 금액 정보 (위치 20)
   -------------------------------------------------- */
{
  id:              'PriceInfo',
  type:            #COLLECTION,
  label:           '금액 정보',
  position:        20
},
{
  id:              'PriceDetail',
  type:            #FIELDGROUP_REFERENCE,
  label:           '금액 세부사항',
  parentId:        'PriceInfo',
  position:        20,
  targetQualifier: 'PriceGroup'
}   ] ``` - **`@UI.fieldGroup`** - **의미:** 상세 페이지(Object Page) 내에서 **관련된 필드들을 하나의 그룹(구역)으로 묶어서 예쁘게 배치**하고자 할 때 그룹 ID를 지정하는 속성입니다. - **사용법 및 옵션:** - `[{ qualifier: 'GeneralInfo', position: 10, label: '만료일자' }]` - `qualifier`: 그룹의 고유 고스트 이름(ID)입니다. 나중에 이 ID를 가진 필드들만 한곳에 모여서 화면에 그려집니다. ### 요약 > 💡 **상세 페이지에만 필드를 보여주고 싶을 때**: `@UI.lineItem`은 적지 않고, `@UI.identification` 또는 `@UI.fieldGroup`만 적는다. > - **화면에서 완전히 숨기고 싶을 때**: `@UI.hidden: true`를 선언한다. > - **상세 페이지에 필드를 이쁘게 구획화할 때**: `@UI.fieldGroup`으로 묶고, 상단에 `@UI.facet`으로 출력할 방을 파준다.
이 기사는 저작권자의 CC BY 4.0 라이센스를 따릅니다.