CEL을 사용하여 변환 표현식을 작성하여 CloudEvents 데이터를 변환할 수 있습니다. 자세한 내용은 수신된 이벤트 변환을 참고하세요.
다음은 CEL 표현식을 작성하여 이벤트 데이터를 변환하는 방법을 보여주는 몇 가지 일반적인 사용 사례와 예시입니다.
표준 사용 사례
다음은 이벤트 데이터를 변환할 때의 몇 가지 표준 사용 사례입니다.
데이터 정규화
다운스트림 서비스에서 더 쉽게 처리할 수 있도록 이벤트 메시지에서 중첩된 데이터 구조를 평면화해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View" } } } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "orderId": "12345", "customerFirstName": "Alex", "customerLastName": "Taylor", "customerStreet": "1800 Amphibious Blvd.", "customerCity": "Mountain View" } }
- 해결 방법 1:
출력 데이터의 형식을 수동으로 지정합니다. 이렇게 하면 필드 이름을 나열하고 출력에 필요한 요소만 선택할 수 있습니다. 이는 입력이 예측 가능하고 필드 수가 적은 경우에 적합한 접근 방식입니다.
setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다. 예를 들면 다음과 같습니다.message.setField("data", { "orderId": message.data.orderId, "customerFirstName": message.data.customer.firstName, "customerLastName": message.data.customer.lastName, "customerStreet": message.data.customer.address.street, "customerCity": message.data.customer.address.city, })
- 해결 방법 2:
표현식에서 함수를 사용합니다.
setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.denormalize
함수는 깊은 구조를 키-값 쌍 목록으로 평면화합니다. 필드 이름은 구조 계층 구조를 분할하기 위해 마침표 (.
)를 사용하여 구분됩니다. 예를 들면 다음과 같습니다.message.setField("data", message.data.denormalize())
예상 페이로드와 약간 다른 다음 출력이 생성됩니다. 그러나 이 방법의 장점은 모든 입력에 작동하고 수신되는 필드의 개수와 관계없이 자동으로 포함되는 더 짧은 CEL 표현식을 사용할 수 있다는 점입니다.
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.address.street": "1800 Amphibious Blvd.", "customer.address.city": "Mountain View" } }
데이터 마스킹
민감한 데이터를 보안 수준이 낮은 환경으로 전송하기 전에 이벤트 페이로드에서 마스킹해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "userId": "user123", "email": "alex@example.com", "creditCardNumber": "1234-5678-9012-3456" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "userId": "user123", "email": "a***@example.com", "creditCardNumber": "xxxx-xxxx-xxxx-3456" } }
- 솔루션:
표현식을 사용하여 이메일 주소, 신용카드 번호와 같은 민감한 정보를 마스킹합니다.
setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.extract
정규 표현식 함수는 RE2 문법을 따릅니다. 예를 들면 다음과 같습니다.message .setField("data.email", re.extract(message.data.email, "(^.).*@(.*)", "\\1***@\\2")) .setField("data.creditCardNumber", re.extract(message.data.creditCardNumber, "(\\d{4})\\D*$", "xxxx-xxxx-xxxx-\\1"))
데이터 삭제
특정 조건에 따라 이벤트 페이로드에서 특정 필드를 삭제해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "orderId": "12345", "customerType": "gold", "discountCode": "VIP" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ { "orderId": "12345", "customerType": "gold" } }
- 솔루션:
customerType
이 'gold'인 경우discountCode
필드를 삭제하는 표현식을 사용합니다.removeFields
함수는 이벤트에서 특정 필드를 삭제합니다. 예를 들면 다음과 같습니다.message.data.customerType == "gold" ? message.removeFields(["data.discountCode"]) : message
데이터 변환
데이터를 한 형식 또는 유형에서 다른 형식 또는 유형으로 변환해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "orderDate": "2024-10-31T12:00:00Z", "totalAmount": "1500" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "orderDate": 1704086400, "totalAmount": 1500.00 } }
- 솔루션:
orderDate
를 UNIX 타임스탬프로 변환하고totalAmount
유형을string
에서double
(부동 소수점 수)로 변환하는 표현식을 사용합니다.setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다. 문자열 조작 함수를 사용하여 문자열 결과를 변환할 수 있습니다. 예를 들면 다음과 같습니다.message .setField("data.orderDate", int(timestamp(message.data.orderDate))) .setField("data.totalAmount", double(message.data.totalAmount))
조건부 라우팅
이벤트 데이터에 따라 이벤트를 여러 대상에 라우팅해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "eventType": "order.created", "orderValue": 200 } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "eventType": "order.created", "orderValue": 200, "routingKey": "highValue" } }
- 솔루션:
orderValue
가 100보다 크면routingKey
필드에 'highValue'를 추가하는 표현식을 사용하고, 그렇지 않으면"normal"
를 사용합니다.routingKey
필드를 사용하여 라우팅 경로를 결정할 수 있습니다.setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다. 예를 들면 다음과 같습니다.message.data.orderValue > 100 ? message.setField("data.routingKey", "highValue") : message.setField("data.routingKey", "normal")
기본값 처리
이벤트 페이로드의 특정 필드에 기본값이 없는 경우 기본값을 지정해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "itemName": "Product A" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "itemName": "Product A", "quantity": 1 } }
- 솔루션:
필드가 아직 없는 경우 기본값이
1
인quantity
필드를 추가하는 표현식을 사용합니다.has
매크로는 필드를 사용할 수 있는지 테스트합니다.setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다. 예를 들면 다음과 같습니다.has(message.data.quantity) ? message : message.setField("data.quantity", 1)
문자열 조작
이벤트 데이터에서 문자열 필드의 일부를 추출하거나 수정해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "customerEmail": "alex@example.com" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "customerEmail": "alex@example.com", "emailDomain": "example.com" } }
- 솔루션:
customerEmail
필드에서 도메인 이름 ('example.com')을 추출하여 새emailDomain
필드에 저장하는 표현식을 사용합니다.setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.extract
정규 표현식 함수는 RE2 문법을 따릅니다. 예를 들면 다음과 같습니다.message .setField("data.emailDomain", re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))
작업 및 매핑 작업
이벤트 데이터에서 목록 또는 지도로 작업해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "productIds": [ "product123", "product456" ] } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "productIds": [ "product123", "product456" ], "productFound": true } }
- 솔루션:
productIds
목록에 'product456'이 있는지 확인하고 결과 (true
또는false
)를 새productFound
필드에 저장하는 표현식을 사용합니다.setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.exists
매크로는 목록의 모든 요소에 조건자가 적용되는지 테스트하고 결과를 'or' 연산자와 결합합니다. 예를 들면 다음과 같습니다.message.setField("data.productFound", message.data.productIds.exists(id, id == "product123"))
오류 처리
이벤트 페이로드에서 잠재적 오류나 예상치 못한 데이터를 적절하게 처리해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "quantity": "abc" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "quantity": 0, "error": "Invalid quantity" } }
- 솔루션:
quantity
필드를 정수로 변환하려는 표현식을 사용합니다. 변환에 실패하면quantity
필드를0
로 설정하고 값이 'Invalid quantity'인 새error
필드를 추가합니다.has
매크로는 필드를 사용할 수 있는지 테스트합니다.type
함수는 값의 유형을 반환합니다.matches
정규 표현식 함수는 RE2 문법을 따릅니다.setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.
예를 들면 다음과 같습니다.
// Check if data.quantity exists has(message.data.quantity) && // Check if data.quantity is a string type(message.data.quantity) == string && // Check if string consists of digits message.data.quantity.matches(r'^-?[0-9]+$') ? // If data.quantity is valid, use message message : // If data.quantity is invalid, set to 0 and generate error message .setField("data.quantity", 0) .setField("data.error", "Invalid quantity")
복잡한 사용 사례
다음은 이벤트 데이터를 변환할 때의 몇 가지 복잡한 사용 사례입니다.
데이터 변환
중첩된 이벤트 데이터에 여러 변환을 실행해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "email": "alex@example.com", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View", "state": "CA" } }, "items": [ { "itemId": "item1", "price": 10.00, "quantity": 2 }, { "itemId": "item2", "price": 5.00, "quantity": 1 } ] } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.email": "a***@example.com", "customer.address.city": "Mountain View", "customer.address.state": "CA" } }
- 솔루션:
주소에서 도시와 주를 추출하고 이메일 주소를 마스킹하는 표현식을 사용합니다.
setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.toMap
함수는 CEL 맵의 CEL 목록을 단일 CEL 맵으로 변환합니다.extract
정규 표현식 함수는 RE2 문법을 따릅니다.removeFields
함수는 이벤트에서 특정 필드를 삭제합니다.denormalize
함수는 깊은 구조를 키-값 쌍 목록으로 평면화합니다. 필드 이름은 구조 계층 구조를 분할하기 위해 마침표 (.
)를 사용하여 구분됩니다.
예를 들면 다음과 같습니다.
message .setField("data", message.data.setField("customer.address", message.data.customer.address.map(key, key == "city" || key == "state", { key: message.data.customer.address[key] }).toMap()) .setField("customer.email", re.extract(message.data.customer.email, "(^..?).*@(.*)", "\\1***@\\2")) .removeFields(["items"]) .denormalize() )
데이터 형식 지정 및 라우팅
이벤트 데이터의 형식을 지정하고 제품 정보를 추가한 다음 이벤트 메시지를 라우팅해야 합니다.
- 시나리오:
다음 CloudEvents 데이터가 제공됩니다.
{ "data": { "productId": "p123", "productName": "Example Product", "category": "electronics" } }
다음과 같은 출력을 생성하는 CEL 표현식을 작성하려고 합니다.
{ "data": { "productId": "electronics-p123", "productName": "EXAMPLE PRODUCT", "category": "electronics", "routingKey": "electronics" } }
- 솔루션:
제품 이름의 형식을 대문자로 지정하고, 카테고리를 기반으로 제품 ID에 접두사를 추가하며, 다운스트림 처리를 위한 라우팅 키를 포함하는 표현식을 사용합니다.
setField
함수는 이벤트의 필드를 지정된 키로 추가하거나 바꿉니다.upperAscii
함수는 모든 ASCII 문자가 해당 대문자로 변환된 문자열을 반환합니다. 예를 들면 다음과 같습니다.message .setField("data.productId", message.data.category + "-" + message.data.productId) .setField("data.productName", message.data.productName.upperAscii()) .setField("data.routingKey", message.data.category)