📖 개요: 이 글에서 다루는 것
SAP Fiori 앱을 새로 만들 때 가장 먼저 마주치는 갈림길이 바로 Fiori Elements와 Freestyle UI5의 선택입니다. 같은 SAPUI5 프레임워크 위에서 동작하지만, 개발 속도·커스터마이징 자유도·유지보수 비용이 크게 달라지기 때문에 초기 결정이 프로젝트 전체를 좌우합니다. 이 글을 끝까지 읽으면 다음을 할 수 있게 됩니다.
- 두 방식의 구조적 차이(메타데이터 주도 vs 코드 주도)를 설명할 수 있다
- manifest.json과 annotation만으로 List Report 앱의 뼈대를 구성할 수 있다
- Freestyle Controller에서 에러 처리와 로깅을 구현할 수 있다
- 프로젝트 요구사항·팀 역량·유지보수 계획 기준으로 선택 근거를 세울 수 있다
📚 미리 알아두면 좋은 배경
SAPUI5의 MVC 구조(View/Controller/Model)와 OData 서비스의 기본 개념을 알고 있으면 수월합니다. OData V4의 엔터티 셋, 바인딩 문법({path}), 그리고 CDS 뷰가 무엇인지 정도만 이해하고 있어도 충분히 따라올 수 있는 중급 난이도의 내용입니다.
🔧 테스트 환경
이 글의 예제는 다음 환경을 기준으로 작성했습니다.
- SAPUI5 1.120 이상 (장기 유지보수 버전 기준, Fiori Elements OData V4 템플릿인
sap.fe.templates사용) - SAP Business Application Studio 또는 VS Code + SAP Fiori tools 확장
- 백엔드: S/4HANA(온프레미스 2022 이상 또는 Cloud)의 RAP 기반 OData V4 서비스, 혹은 SAP BTP의 CAP 서비스
- Node.js 18 이상 (Fiori tools 로컬 미리보기용)
OData V2 기반의 구형 시스템(예: SAP Gateway + SEGW)에서도 Fiori Elements를 쓸 수 있지만, 이 경우 템플릿이 sap.suite.ui.generic.template 계열로 달라진다는 점을 기억해 두세요. 신규 프로젝트라면 일반적으로 V4 스택이 권장됩니다.
💡 핵심 개념: 두 방식의 구조적 차이
비유하자면 Fiori Elements는 조립식 아파트, Freestyle UI5는 맞춤 건축입니다. 조립식 아파트는 설계도(annotation)만 제출하면 시공(렌더링)은 표준 공법이 알아서 처리합니다. 반면 맞춤 건축은 벽 하나, 창문 하나까지 직접 설계하는 대신 원하는 모든 형태를 구현할 수 있습니다.
동작 원리로 풀면 이렇습니다. Fiori Elements 앱에는 개발자가 작성한 View가 거의 없습니다. 런타임에 프레임워크가 OData 메타데이터 + UI annotation을 읽어 List Report, Object Page 같은 표준 플로어플랜을 동적으로 생성합니다. 즉 "무엇을 보여줄지"만 선언하면 "어떻게 보여줄지"는 SAP가 관리하는 템플릿이 책임집니다. 그래서 UI5 버전이 올라가면 앱을 고치지 않아도 새 디자인 가이드라인과 접근성 개선이 자동 반영되는 경우가 많습니다.
Freestyle은 정반대로, XML View와 Controller를 개발자가 전부 작성합니다. 화면 배치·인터랙션·상태 관리가 모두 코드에 있으므로 자유도는 무한에 가깝지만, 그만큼 일관성 유지와 업그레이드 대응도 개발팀의 몫입니다.
| 비교 항목 | Fiori Elements | Freestyle UI5 |
|---|---|---|
| 개발 속도 | CRUD 앱 기준 매우 빠름 | 화면당 공수 큼 |
| 커스터마이징 | 확장 포인트 범위 내 | 완전 자유 |
| OData annotation 의존도 | 매우 높음 (핵심 수단) | 낮음 (선택 사항) |
| UI 일관성/접근성 | 템플릿이 자동 보장 수준으로 처리 | 개발자가 직접 관리 |
| 유지보수 | 버전업 시 개선 자동 수용 | 회귀 테스트 부담 큼 |
| 적합 시나리오 | 목록-상세형 업무 앱, 승인/조회 | 대시보드, 위저드, 특수 UX |
선택 기준을 실무 언어로 정리하면 이렇습니다. 요구사항이 표준 플로어플랜(List Report, Object Page, Overview Page, Analytical List Page)으로 80% 이상 커버되면 Fiori Elements가 일반적으로 유리합니다. 반대로 화면 설계서에 표준 컨트롤로 표현하기 어려운 인터랙션(드래그 기반 플래너, 캔버스형 시각화 등)이 많다면 Freestyle이 낫습니다. 팀 역량도 변수입니다. ABAP/CDS에 강한 팀은 annotation 중심의 Fiori Elements가, JavaScript에 강한 팀은 Freestyle이 생산성이 높게 나오는 경향이 있습니다. 최근에는 Fiori Elements 위에 Freestyle 조각(Custom Page, Building Block)을 얹는 Flexible Programming Model이 중간 지대를 제공하므로, "전부 아니면 전무" 식 선택은 피하는 것이 좋습니다.
💻 실전 예제 3단계 비교
1단계 — Fiori Elements 기본: 견적서 List Report
판매 견적(SalesQuote) 조회 앱을 가정합니다. Fiori Elements에서는 View 파일 없이 manifest.json의 라우팅 타깃이 표준 템플릿 컴포넌트를 가리킵니다.
{
"sap.app": {
"id": "com.bts.salesquote",
"dataSources": {
"quoteService": {
"uri": "/sap/opu/odata4/sap/zui_quote_o4/srvd/sap/zui_quote/0001/",
"type": "OData",
"settings": { "odataVersion": "4.0" }
}
}
},
"sap.ui5": {
"routing": {
"targets": {
"QuoteListTarget": {
"type": "Component",
"name": "sap.fe.templates.ListReport",
"options": {
"settings": { "contextPath": "/SalesQuote" }
}
}
}
}
}
}
화면에 어떤 컬럼과 필터가 나올지는 백엔드 CDS annotation이 결정합니다.
annotate view ZC_SalesQuote with
{
@UI.lineItem: [{ position: 10, importance: #HIGH }]
@UI.selectionField: [{ position: 10 }]
QuoteId;
@UI.lineItem: [{ position: 20 }]
BuyerName;
@UI.lineItem: [{ position: 30, criticality: 'ApprovalCriticality' }]
ApprovalStatus;
}
이 두 파일이 사실상 개발의 전부입니다. 테이블, 필터바, 정렬, 개인화(Variant)까지 템플릿이 만들어 줍니다. Freestyle로 동일 기능을 만들면 View·Controller·필터 로직을 합쳐 수백 줄이 필요합니다.
2단계 — Freestyle 실무: 에러 처리와 로깅이 있는 견적 보드
이번엔 같은 데이터를 카드형 보드로 보여주는 Freestyle 화면입니다. 실무에서는 조회 실패 시 사용자 안내와 운영 로그를 반드시 남겨야 합니다.
sap.ui.define([
"sap/ui/core/mvc/Controller",
"sap/m/MessageBox",
"sap/base/Log"
], (Controller, MessageBox, Log) => {
"use strict";
return Controller.extend("com.bts.quoteboard.controller.Board", {
onRefreshQuotes() {
const oBinding = this.byId("quoteGrid").getBinding("items");
oBinding.attachEventOnce("dataReceived", (oEvent) => {
const oError = oEvent.getParameter("error");
if (oError) {
Log.error("견적 보드 조회 실패", oError.message, "com.bts.quoteboard");
MessageBox.error("견적 데이터를 불러오지 못했습니다. 잠시 후 다시 시도해 주세요.");
return;
}
Log.info(`견적 ${oBinding.getCount()}건 로드 완료`, null, "com.bts.quoteboard");
});
oBinding.refresh();
}
});
});
Fiori Elements라면 이 에러 다이얼로그·재시도 안내가 템플릿에 내장되어 있어 별도 코드가 필요 없습니다. 반대로 "카드형 보드" 자체는 표준 플로어플랜에 없으므로 Freestyle(또는 FE Custom Page)이 필요합니다. 이것이 두 방식의 트레이드오프를 가장 잘 보여주는 지점입니다.
3단계 — 프로덕션: 성능 설정과 확장 포인트
Fiori Elements를 운영 수준으로 다듬을 때는 manifest 설정으로 초기 로드와 테이블 동작을 제어합니다.
"options": {
"settings": {
"contextPath": "/SalesQuote",
"initialLoad": "Disabled",
"variantManagement": "Page",
"controlConfiguration": {
"@com.sap.vocabularies.UI.v1.LineItem": {
"tableSettings": {
"type": "ResponsiveTable",
"selectionMode": "Single",
"enablePaste": false
}
}
}
}
}
initialLoad: "Disabled"는 사용자가 필터를 지정하기 전 대량 조회를 막아 백엔드 부하를 줄이는 대표적인 성능 옵션입니다. 표준으로 부족한 로직은 Controller Extension으로 주입합니다.
sap.ui.define([
"sap/ui/core/mvc/ControllerExtension"
], (ControllerExtension) => {
"use strict";
return ControllerExtension.extend("com.bts.salesquote.ext.ListExt", {
override: {
editFlow: {
onBeforeSave(mParameters) {
// 저장 전 검증: 만료된 견적은 저장 차단
const oCtx = mParameters.context;
if (oCtx.getProperty("IsExpired")) {
return Promise.reject("만료된 견적은 수정할 수 없습니다.");
}
}
}
}
});
});
품질 확보 측면에서는 두 방식 모두 OPA5(화면 흐름 테스트)와 QUnit(단위 테스트)을 사용하며, Fiori Elements는 sap/fe/test 네임스페이스의 전용 테스트 API로 표준 플로어플랜 시나리오를 짧게 기술할 수 있습니다. 보안 관점에서는 두 방식 모두 OData 모델이 CSRF 토큰을 자동 처리하지만, Freestyle에서 직접 fetch로 백엔드를 호출하는 코드를 넣는 순간 토큰·인코딩 처리가 개발자 책임이 된다는 점을 주의해야 합니다.
⚠️ 삽질 노트 — 자주 만나는 함정 FAQ
Q1. Fiori Elements 화면이 텅 비어 나옵니다.
대부분 annotation 누락입니다. @UI.lineItem이 하나도 없으면 테이블 컬럼이 생성되지 않습니다. 브라우저에서 $metadata를 열어 UI 어노테이션이 실제로 내려오는지, 그리고 manifest의 contextPath가 엔터티 셋 이름과 정확히 일치하는지 먼저 확인하세요.
Q2. Fiori Elements로 시작했는데 커스텀 요구가 계속 늘어납니다. 갈아엎어야 하나요?
바로 재작성하기 전에 Flexible Programming Model의 Custom Section, Custom Page, Building Block으로 흡수 가능한지 검토하는 것이 일반적으로 안전합니다. 확장 코드가 앱의 절반을 넘어가기 시작하면 그때 Freestyle 전환을 논의해도 늦지 않습니다.
Q3. Freestyle에서 UI5 버전을 올렸더니 화면이 깨졌습니다.
사용 중단(deprecated) API를 쓰고 있을 가능성이 큽니다. UI5 linter나 지원 어시스턴트로 사용 중단 API를 점검하고, 버전업 전 OPA5 회귀 테스트를 돌리는 절차를 팀 표준으로 만들어 두세요. Fiori Elements 대비 Freestyle이 버전업 비용이 큰 이유가 바로 이 지점입니다.
Q4. 두 방식을 한 프로젝트에 섞어도 되나요?
됩니다. 실제로 목록-상세 앱은 Fiori Elements, 특수 화면 한두 개만 Freestyle로 만들어 Launchpad에서 함께 배포하는 구성이 흔합니다. 다만 UX 일관성을 위해 Freestyle 쪽도 Fiori 디자인 가이드라인을 따르는 것이 권장됩니다.
🚀 더 파볼 주제
이 글에서 다진 선택 기준 위에 다음 주제를 얹으면 실전 활용 폭이 넓어집니다. Fiori Elements 트랙에서는 Flexible Programming Model의 Building Block과 RAP 기반 트랜잭션 앱(draft 처리)을, Freestyle 트랙에서는 TypeScript 기반 UI5 개발과 OPA5 자동화 테스트 파이프라인을 추천합니다. 두 트랙의 공통 기반으로 OData V4 바인딩 심화도 함께 살펴보면 좋습니다.
📚 더 읽어볼 자료
댓글 0
아직 댓글이 없습니다.