CAP for Node

URL 직접 넣는 개발자 90% — Destination으로 #shorts #SAP #CAPforNode

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

아직 댓글이 없습니다.