URL 하드코딩의 문제점
CAP for Node.js에서 외부 서비스를 호출할 때 URL을 소스 코드나 환경변수에 직접 하드코딩하는 방식은 개발, QA, 운영 환경별로 URL을 관리하기 어렵고, 인증 정보 유출 위험이 있습니다. SAP BTP Destination 서비스를 사용하면 URL, 인증 정보, 헤더를 중앙에서 관리할 수 있습니다.
URL 하드코딩 — 잘못된 패턴
// 잘못된 패턴: URL 직접 하드코딩
const axios = require('axios');
this.on('getProductPrice', async (req) => {
const { productId } = req.data;
// 개발/운영마다 URL이 다르고, 토큰도 소스에 노출
const response = await axios.get(
`https://s4hana-prod.company.com/sap/opu/odata/sap/ZPRODUCT_SRV/ProductSet('${productId}')`,
{
headers: {
'Authorization': 'Basic ' + Buffer.from('user:password').toString('base64')
}
}
);
return response.data;
});
BTP Destination 설정
# BTP Cockpit → Connectivity → Destinations → New
# Destination 이름: S4HANA_PROD
# Type: HTTP
# URL: https://s4hana-prod.company.com
# Authentication: BasicAuthentication
# User: BAPI_USER
# Password: (안전하게 저장)
# Additional Properties:
# sap-client: 100
# WebIDEEnabled: true
CAP에서 Destination 사용 — cds.env.requires
// package.json 또는 .cdsrc.json에서 Destination 참조
{
"cds": {
"requires": {
"S4HANA_PROD": {
"kind": "odata-v2",
"model": "srv/external/S4HANA_PROD",
"[production]": {
"credentials": {
"destination": "S4HANA_PROD",
"path": "/sap/opu/odata/sap/ZPRODUCT_SRV"
}
},
"[development]": {
"credentials": {
"url": "http://localhost:4004"
}
}
}
}
}
}
// 서비스 핸들러에서 Destination 사용
const cds = require('@sap/cds');
module.exports = cds.service.impl(async function() {
const S4 = await cds.connect.to('S4HANA_PROD');
this.on('getProductPrice', async (req) => {
const { productId } = req.data;
// URL, 인증 정보 모두 Destination에서 자동 로드
const product = await S4.run(
SELECT.one.from('ProductSet')
.where({ ProductId: productId })
.columns(['ProductId', 'ProductName', 'Price', 'Currency'])
);
if (!product) {
return req.error(404, `상품 ${productId}를 찾을 수 없습니다.`);
}
return product;
});
});
로컬 개발 시 Mock 서비스 활용
// srv/external/S4HANA_PROD.cds (외부 서비스 모델)
@cds.external
service S4HANA_PROD {
entity ProductSet {
key ProductId: String(18);
ProductName: String(100);
Price: Decimal(15, 2);
Currency: String(3);
}
}
// test/ProductSet.json (로컬 Mock 데이터)
[
{ "ProductId": "P001", "ProductName": "노트북", "Price": 1500000, "Currency": "KRW" },
{ "ProductId": "P002", "ProductName": "마우스", "Price": 45000, "Currency": "KRW" }
]
// .cdsrc.json 로컬 개발 설정
{
"requires": {
"S4HANA_PROD": {
"[development]": {
"kind": "odata",
"credentials": {
"url": "http://localhost:4004"
}
}
}
}
}
Principal Propagation이 필요한 경우
// Destination 설정에서 PrincipalPropagation 활성화 시
// cds.connect.to()가 현재 사용자 JWT를 자동 전달
const S4 = await cds.connect.to('S4HANA_PP'); // PP = PrincipalPropagation
// req.user 정보가 S/4HANA 호출에 자동 포함됨
const orders = await S4.run(
SELECT.from('A_SalesOrder')
.where({ SoldToParty: req.user.id })
);
환경별 Destination 관리
- 개발: localhost Mock 또는 SAP 샌드박스 시스템
- QA: 별도 Destination(S4HANA_QA)으로 QA 시스템 연결
- 운영: Destination 이름은 동일(S4HANA_PROD), URL만 운영 시스템으로
- 소스 코드 변경 없이 환경 전환 가능
공식 문서
CAP Destination 서비스 연동 가이드는 cap.cloud.sap/docs/guides/using-services에서 확인하세요.
댓글 0
아직 댓글이 없습니다.