Pode transformar os seus dados CloudEvents escrevendo expressões de transformação com CEL. Para mais informações, consulte o artigo Transforme eventos recebidos.
Seguem-se alguns exemplos de utilização comuns que mostram como escrever expressões CEL para transformar os dados de eventos.
Exemplos de utilização padrão
Seguem-se alguns exemplos de utilização padrão quando transforma dados de eventos.
Normalização de dados
Tem de nivelar uma estrutura de dados aninhada na sua mensagem de evento para permitir um processamento mais fácil por parte de um serviço a jusante.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "orderId": "12345", "customer": { "firstName": "Alex", "lastName": "Taylor", "address": { "street": "1800 Amphibious Blvd.", "city": "Mountain View" } } } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "orderId": "12345", "customerFirstName": "Alex", "customerLastName": "Taylor", "customerStreet": "1800 Amphibious Blvd.", "customerCity": "Mountain View" } }
- Solução 1:
Formate os dados de saída manualmente. Isto permite-lhe listar os nomes dos campos e escolher apenas os elementos necessários no resultado. Esta é uma abordagem razoável quando a entrada é previsível e quando o número de campos é baixo. A função
setField
adiciona ou substitui um campo do evento por uma determinada chave. Por exemplo: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, })
- Solução 2:
Use uma função na sua expressão. A função
setField
adiciona ou substitui um campo do evento por uma determinada chave. A funçãodenormalize
reduz as estruturas complexas a uma lista de pares de chave e valor. Os nomes dos campos são delimitados com um ponto (.
) para segmentar a hierarquia da estrutura. Por exemplo:message.setField("data", message.data.denormalize())
Isto resulta no seguinte resultado, que difere ligeiramente da carga útil esperada. No entanto, as vantagens incluem uma expressão CEL mais curta que funciona em qualquer entrada e que inclui automaticamente qualquer número de campos recebidos.
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.address.street": "1800 Amphibious Blvd.", "customer.address.city": "Mountain View" } }
Ocultação de dados
Tem de ocultar dados confidenciais num payload de eventos antes de o enviar para um ambiente menos seguro.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "userId": "user123", "email": "alex@example.com", "creditCardNumber": "1234-5678-9012-3456" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "userId": "user123", "email": "a***@example.com", "creditCardNumber": "xxxx-xxxx-xxxx-3456" } }
- Solução:
Use uma expressão para ocultar informações confidenciais, como o endereço de email e o número do cartão de crédito. A função
setField
adiciona ou substitui um campo do evento por uma determinada chave. A função de expressão regular segue a sintaxe RE2.extract
Por exemplo: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"))
Ocultação de dados
Tem de remover campos específicos de uma carga útil de eventos com base em determinadas condições.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "orderId": "12345", "customerType": "gold", "discountCode": "VIP" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ { "orderId": "12345", "customerType": "gold" } }
- Solução:
Use uma expressão que oculte o campo
discountCode
se o campocustomerType
for "gold". A funçãoremoveFields
remove campos específicos de um evento. Por exemplo:message.data.customerType == "gold" ? message.removeFields(["data.discountCode"]) : message
Conversão de dados
Precisa de converter dados de um formato ou tipo para outro.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "orderDate": "2024-10-31T12:00:00Z", "totalAmount": "1500" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "orderDate": 1704086400, "totalAmount": 1500.00 } }
- Solução:
Use uma expressão que converta
orderDate
numa indicação de tempo UNIX e o tipototalAmount
destring
paradouble
(número de vírgula flutuante). A funçãosetField
adiciona ou substitui um campo do evento por uma determinada chave. Pode usar funções de manipulação de strings para converter os resultados de strings. Por exemplo:message .setField("data.orderDate", int(timestamp(message.data.orderDate))) .setField("data.totalAmount", double(message.data.totalAmount))
Encaminhamento condicional
Precisa de encaminhar eventos para diferentes destinos com base nos dados de eventos.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "eventType": "order.created", "orderValue": 200 } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "eventType": "order.created", "orderValue": 200, "routingKey": "highValue" } }
- Solução:
Use uma expressão que adicione um campo
routingKey
com um "highValue" se oorderValue
for superior a 100; caso contrário,"normal"
. O camporoutingKey
pode ser usado para determinar o caminho de encaminhamento. A funçãosetField
adiciona ou substitui um campo do evento por uma determinada chave. Por exemplo:message.data.orderValue > 100 ? message.setField("data.routingKey", "highValue") : message.setField("data.routingKey", "normal")
Processamento de valores predefinidos
Tem de garantir que determinados campos na carga útil do evento têm valores predefinidos se não estiverem presentes.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "itemName": "Product A" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "itemName": "Product A", "quantity": 1 } }
- Solução:
Use uma expressão que adicione um campo
quantity
com um valor predefinido de1
se o campo ainda não existir. A macrohas
testa se um campo está disponível. A funçãosetField
adiciona ou substitui um campo do evento por uma determinada chave. Por exemplo:has(message.data.quantity) ? message : message.setField("data.quantity", 1)
Manipulação de strings
Tem de extrair ou modificar partes de um campo de string nos dados de eventos.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "customerEmail": "alex@example.com" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "customerEmail": "alex@example.com", "emailDomain": "example.com" } }
- Solução:
Use uma expressão que extraia o nome do domínio ("example.com") do campo
customerEmail
e o armazene num novo campoemailDomain
. A funçãosetField
adiciona ou substitui um campo do evento por uma determinada chave. A função de expressão regular segue a sintaxe RE2.extract
Por exemplo:message .setField("data.emailDomain", re.extract(message.data.customerEmail, "(^.*@)(.*)", "\\2"))
Operações de listas e mapas
Precisa de trabalhar com listas ou mapas nos dados de eventos.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "productIds": [ "product123", "product456" ] } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "productIds": [ "product123", "product456" ], "productFound": true } }
- Solução:
Use uma expressão que verifique se "product456" existe na lista e armazene o resultado (
true
oufalse
) num novo campoproductFound
.productIds
A funçãosetField
adiciona ou substitui um campo do evento por uma determinada chave. A macroexists
testa se um predicado se aplica a todos os elementos de uma lista e combina os resultados com o operador "ou". Por exemplo:message.setField("data.productFound", message.data.productIds.exists(id, id == "product123"))
Processamento de erros
Tem de processar corretamente potenciais erros ou dados inesperados no payload do evento.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "quantity": "abc" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "quantity": 0, "error": "Invalid quantity" } }
- Solução:
Use uma expressão que tente converter o campo
quantity
num inteiro. Se a conversão falhar, defina o campoquantity
como0
e adicione um novo campoerror
com o valor "Quantidade inválida".- A macro
has
testa se um campo está disponível. - A função
type
devolve o tipo de um valor. - A função de expressão regular
matches
segue a sintaxe RE2. - A função
setField
adiciona ou substitui um campo do evento por uma determinada chave.
Por exemplo:
// 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")
- A macro
Exemplos de utilização complexos
Seguem-se alguns exemplos de utilização complexos ao transformar dados de eventos.
Transformação de dados
Tem de realizar várias transformações em dados de eventos aninhados.
- Cenário:
Tendo em conta os seguintes dados de 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 } ] } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "orderId": "12345", "customer.firstName": "Alex", "customer.lastName": "Taylor", "customer.email": "a***@example.com", "customer.address.city": "Mountain View", "customer.address.state": "CA" } }
- Solução:
Use uma expressão que extraia a cidade e o estado da morada e que oculte o endereço de email.
- A função
setField
adiciona ou substitui um campo do evento por uma determinada chave. - A função
toMap
converte uma lista de CEL de mapas CEL num único mapa CEL. - A função de expressão regular
extract
segue a sintaxe RE2. - A função
removeFields
remove campos específicos de um evento. - A função
denormalize
reduz as estruturas complexas a uma lista de pares de chave e valor. Os nomes dos campos são delimitados com um ponto (.
) para segmentar a hierarquia da estrutura.
Por exemplo:
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() )
- A função
Formatação e encaminhamento de dados
Tem de formatar os dados de eventos, adicionar informações sobre os produtos e, em seguida, encaminhar a mensagem de evento.
- Cenário:
Tendo em conta os seguintes dados de CloudEvents:
{ "data": { "productId": "p123", "productName": "Example Product", "category": "electronics" } }
Quer escrever uma expressão de IEC que resulte no seguinte resultado:
{ "data": { "productId": "electronics-p123", "productName": "EXAMPLE PRODUCT", "category": "electronics", "routingKey": "electronics" } }
- Solução:
Usar uma expressão que formata o nome do produto em maiúsculas, adiciona um prefixo ao ID do produto com base na respetiva categoria e inclui uma chave de encaminhamento para processamento a jusante. A função
setField
adiciona ou substitui um campo do evento por uma determinada chave. A funçãoupperAscii
devolve uma string com todos os carateres ASCII convertidos nos respetivos carateres maiúsculos correspondentes. Por exemplo:message .setField("data.productId", message.data.category + "-" + message.data.productId) .setField("data.productName", message.data.productName.upperAscii()) .setField("data.routingKey", message.data.category)