CAP for Java

Action 핸들러 Map 접근 그만 #shorts #SAP #CAP

▶ YouTube에서 보기

Map으로 파라미터를 접근하는 방식의 문제점

CAP for Java에서 Action 파라미터를 처리할 때 많은 개발자가 Map<String, Object>로 직접 캐스팅해서 값을 꺼냅니다. 이 방식은 컴파일 시점에 오류를 잡을 수 없고, 필드 이름을 잘못 적어도 런타임에 null만 반환합니다. CDS 생성 POJO(Plain Old Java Object)를 사용하면 타입 안전성과 IDE 자동완성을 얻을 수 있습니다.

Map 접근 방식 — 타입 안전성 없는 패턴

// CDS 정의
service SalesService {
  action createQuotation(
    customerId  : String;
    validUntil  : Date;
    netAmount   : Decimal;
    currencyCode: String;
    lineItems   : many {
      productId : String;
      quantity  : Integer;
    }
  ) returns Quotations;
}
// 잘못된 패턴: Map으로 직접 접근
@On(event = "createQuotation", service = "SalesService")
public void createQuotation(ActionEventContext ctx) {
    // 안전하지 않은 캐스팅
    @SuppressWarnings("unchecked")
    Map params = (Map) ctx.getParameterInfo().asMap();

    // 오탈자가 있어도 컴파일 오류 없음 — runtime에 null
    String customerId  = (String) params.get("customerid");  // 소문자 오탈자
    String validUntil  = (String) params.get("validUntil");
    BigDecimal amount  = (BigDecimal) params.get("NetAmount"); // 대문자 오탈자

    // 필드 이름이 맞는지 확신할 수 없음
    // IDE 자동완성 없음
    // null 체크를 빠뜨리기 쉬움
}

타입 안전한 파라미터 접근 방법

// 올바른 패턴: getParam()으로 타입 명시
@On(event = "createQuotation", service = "SalesService")
public void createQuotation(ActionEventContext ctx) {
    var params = ctx.getParameterInfo();

    // 타입을 명시적으로 지정
    String customerId    = params.get("customerId", String.class);
    LocalDate validUntil = params.get("validUntil", LocalDate.class);
    BigDecimal netAmount = params.get("netAmount", BigDecimal.class);
    String currencyCode  = params.get("currencyCode", String.class);

    // null 체크
    if (customerId == null || netAmount == null) {
        throw new ServiceException(ErrorStatuses.BAD_REQUEST,
            "customerId와 netAmount는 필수입니다.");
    }

    // 배열 타입 파라미터
    List lineItems = params.get("lineItems", List.class);

    // Row로 각 항목 접근
    if (lineItems != null) {
        for (Row item : lineItems) {
            String productId = item.get("productId", String.class);
            Integer qty = item.get("quantity", Integer.class);
            // 처리 로직
        }
    }
}

CDS 생성 POJO 활용 (가장 권장)

// CDS build 실행 시 Java POJO 자동 생성
// mvn compile → target/generated-sources/cds4j 에 생성됨

// 생성된 클래스 예시 (자동 생성)
// cds.gen.salesservice.CreateQuotationContext
// cds.gen.salesservice.Quotations

// 타입 안전한 POJO 방식
@On(event = CreateQuotationContext.CDS_NAME, service = "SalesService")
public void createQuotation(CreateQuotationContext ctx) {
    // IDE 자동완성 + 컴파일 타임 체크
    String customerId    = ctx.getCustomerId();      // 자동완성
    LocalDate validUntil = ctx.getValidUntil();      // 자동완성
    BigDecimal netAmount = ctx.getNetAmount();        // 자동완성
    String currencyCode  = ctx.getCurrencyCode();    // 자동완성

    // 배열 파라미터도 타입 안전
    List lines = ctx.getLineItems();

    for (var line : lines) {
        String productId = line.getProductId();  // 자동완성
        Integer qty      = line.getQuantity();   // 자동완성
    }

    // 결과 설정
    var quotation = Quotations.create();
    quotation.setCustomerId(customerId);
    quotation.setNetAmount(netAmount);
    quotation.setStatus("DRAFT");

    var saved = persistenceService.run(
        Insert.into(Quotations_.class).entry(quotation)
    ).single(Quotations.class);

    ctx.setResult(saved);  // 타입 안전한 결과 설정
}

CDS4J 코드 생성 설정

// pom.xml에 CDS4J Maven 플러그인 설정
<plugin>
  <groupId>com.sap.cds</groupId>
  <artifactId>cds-maven-plugin</artifactId>
  <executions>
    <execution>
      <id>generate</id>
      <goals><goal>generate</goal></goals>
    </execution>
  </executions>
</plugin>

// 코드 생성
mvn compile

// 생성된 파일 위치
// target/generated-sources/cds4j/
//   cds/gen/salesservice/
//     CreateQuotationContext.java
//     Quotations.java
//     Quotations_.java (쿼리 헬퍼)

타입 안전한 결과 처리

// After 핸들러에서 타입 안전하게 결과 접근
@After(event = CreateQuotationContext.CDS_NAME, service = "SalesService")
public void afterCreateQuotation(CreateQuotationContext ctx) {
    // 결과를 POJO로 읽기
    Quotations result = ctx.getResult();

    // IDE 자동완성으로 필드 접근
    String quotationId = result.getQuotationId();
    String status      = result.getStatus();

    // 후처리 로직
    sendQuotationEmail(quotationId, ctx.getCustomerId());
}

공식 문서

CAP Java CDS 코드 생성과 POJO 활용은 cap.cloud.sap/docs/java에서 확인하세요.

댓글 0

아직 댓글이 없습니다.