Entendendo os operadores JOLT (wildcards)

Aprenda como os wildcards ajudam você a criar regras de transformação JOLT dinâmicas, concisas e adaptáveis.

Os operadores do JOLT, também conhecidos como wildcards, são um dos recursos mais poderosos do framework. Eles permitem manipular valores, capturar nomes de campos, lidar com entradas opcionais e criar estruturas flexíveis mesmo quando o formato de entrada varia.

Neste guia, você verá como cada operador funciona, que tipo de problema ele resolve e como usá-lo para simplificar cenários de transformação básicos e avançados.

Conceitos importantes

Até agora, cobrimos os conceitos essenciais do JOLT. Antes de avançar para as operações avançadas, precisamos apresentar dois elementos fundamentais usados em todas as especificações JOLT: LHS e RHS.

LHS e RHS

Toda operação JOLT é construída em torno de dois lados:

  • LHS (Left Hand Side): A parte antes dos dois-pontos (:), onde selecionamos ou casamos campos da entrada.

  • RHS (Right Hand Side): A parte depois dos dois-pontos (:), onde atribuímos ou mapeamos valores para a saída.

Os operadores se comportam de maneiras diferentes no LHS e no RHS, e entender essa distinção é essencial para criar regras de transformação poderosas e flexíveis.

Exemplo:

[
 {
   "operation": "shift",
   "spec": {
LHS -> "customer": {
 LHS ->  "name": "client.fullName",  <- RHS
 LHS ->  "birhtDate": "client.dateOfBirth",  <- RHS
 LHS ->  "address": "client.address.street",  <- RHS
 LHS ->  "country": "client.address.country"  <- RHS
     }
   }
 }
}

Análise detalhada dos operadores

Vamos analisar cada operador e observar como ele se comporta em transformações reais. Nas próximas seções, você encontrará explicações e exemplos que mostram exatamente como cada operador funciona e qual tipo de saída produz.

& (“e” comercial)

Usa o nome do campo encontrado no LHS para construir a estrutura no JSON de saída, sem exigir que você defina o nome manualmente no RHS.

  • Uso: RHS

  • Operação: shift

Exemplo prático

  • Caso de uso: Agrupar campos relacionados de um cliente em um único objeto.

  • Objetivo: Mover os campos existentes para um novo objeto client sem renomeá-los.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

Essa transformação move os campos originais name e email para dentro de um novo objeto client.

O wildcard & mantém o mesmo nome de campo do input ao criar a estrutura de saída.

  • "name": "client.&" pega o valor de name e o coloca em client.name.

  • "email": "client.&" faz o mesmo para email, gerando client.email.

Ao usar &, você não precisa repetir manualmente cada nome de campo no RHS. O JOLT preserva automaticamente o nome original enquanto organiza os campos dentro de client.

* (asterisco)

Refere-se a todos os campos ou objetos, sem precisar listar cada um explicitamente.

  • Uso: LHS

  • Operações: shift, remove, cardinality, modify-default-beta, modify-overwrite-beta

Exemplo prático

  • Caso de uso: Organizar os dados de um cliente agrupando todos os campos sob um único objeto pai.

  • Objetivo: Aninhar todos os campos dentro de um objeto customer e renomear document para ssn.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

Na linha "*": "customer.&", pegamos qualquer campo encontrado no JSON de entrada e o colocamos dentro de um novo objeto customer, preservando tanto o nome do campo quanto toda a sua estrutura.

Para o campo document, pegamos seu valor e o mapeamos para um novo campo chamado ssn, também dentro do objeto customer.

Como funciona:

  • * corresponde a qualquer campo.

  • & mantém o nome e o valor originais do campo.

  • Quando usados juntos (* + &), o JOLT copia automaticamente todos os campos correspondentes sem que você precise especificá-los um por um.

Essa combinação é útil quando você precisa manipular ou reorganizar um JSON sem conhecer toda a sua estrutura com antecedência.

@ (arroba)

Faz referência ao valor de um campo.

Seu comportamento muda dependendo da operação e de estar no LHS ou RHS.

  • Uso: LHS e RHS

  • Operações: shift, modify-default-beta, modify-overwrite-beta

Exemplo com shift

  • Caso de uso: Criar nomes de campos dinamicamente com base nos valores de entrada.

  • Objetivo: Usar o valor de key para definir o nome do campo dentro de product, atribuindo a ele o valor de value.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

Em product.@(1,key), a expressão @(1,key) diz ao JOLT para:

  • Subir um nível (por causa do 1),

  • Encontrar o campo chamado key,

  • Usar seu valor ("code") como nome do novo campo dentro de product.

Isso significa que o valor de "value" ("123-ABC") é atribuído a um campo com nome dinâmico ("code").

Como o @ funciona:

  • @ faz referência a dados de outra parte do JSON.

  • O primeiro argumento (1) indica quantos níveis acima procurar.

  • O segundo argumento (key) indica qual valor de campo recuperar.

  • A mesma lógica se aplica quando @ é usado no LHS ou RHS do spec.

Esse mecanismo permite criar nomes de campo dinamicamente com base em valores do JSON de entrada, proporcionando transformações mais flexíveis.

Exemplos de modify-default-beta e modify-overwrite-beta

  • Caso de uso: Enriquecer um objeto aninhado com informações armazenadas em outra parte do JSON.

  • Objetivo: Adicionar um campo company dentro de product, usando o valor do campo de nível superior manufacturer.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

Criamos um novo campo chamado company dentro do objeto product e atribuímos a ele o valor do campo manufacturer.

Para isso, usamos @(2,manufacturer), que instrui o JOLT a:

  • Subir dois níveis (a partir de dentro de product),

  • Encontrar o campo chamado manufacturer, Recuperar seu valor e atribuí-lo a product.company.

modify-default-beta vs. modify-overwrite-beta

  • modify-default-beta: Adiciona o campo company somente se ele ainda não existir dentro de product. Ele preserva valores existentes.

  • modify-overwrite-beta: Adiciona o campo company mesmo que ele já exista, sempre substituindo o valor existente. Como o nome sugere, ele sobrescreve qualquer conteúdo anterior.

Ambas as operações usam o mesmo spec de transformação. A única diferença é o comportamento em relação à sobrescrita.

$ (cifrão)

Faz referência ao nome de um campo, em vez de seu valor.

  • Uso: LHS

  • Operação: shift

Exemplo prático

  • Caso de uso: Identificar quais campos existem dentro de um objeto product.

  • Objetivo: Gerar uma lista com os nomes de todos os campos dentro de product.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

Selecionamos todos os campos (*) dentro do objeto product e usamos $ para recuperar o nome de cada campo, não o seu valor. Em seguida, colocamos cada nome recuperado dentro da lista product[].

Isso permite gerar uma estrutura que captura apenas os nomes dos campos do JSON de entrada.

# (cerquilha)

O operador # possui funções diferentes dependendo de onde é usado:

  • Uso:

    • LHS: Permite inserir valores manuais (constantes) no JSON de saída.

    • RHS: Usado exclusivamente para criar listas, agrupando conteúdo de níveis superiores em uma nova estrutura de lista.

  • Operação: shift

Exemplo no LHS

  • Caso de uso: Adicionar um campo ausente que não é fornecido no JSON de entrada.

  • Objetivo: Inserir um campo padrão category dentro de product, preservando todos os campos existentes.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

O valor após o curinga # (DEFAULT-CATEGORY) é inserido manualmente no campo especificado no RHS (product.category).

Isso garante que o campo seja sempre incluído, independentemente da entrada.

Exemplo no RHS

  • Caso de uso: Padronizar nomes de campos dentro de uma lista de objetos products.

  • Objetivo: Renomear o campo value para price em cada item do array products.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

Usar # no RHS significa:

  • Estamos criando uma lista ([...]).

  • #2 indica ao JOLT que deve agrupar os elementos com base na estrutura encontrada dois níveis acima.

  • Isso garante que cada code e seu respectivo price permaneçam juntos dentro do mesmo objeto product.

Portanto:

  • "code": "products[#2].&": Pega o valor de code e o coloca no campo code dentro da nova lista products.

  • "value": "products[#2].price": Pega o campo value e o grava como price dentro do mesmo item da lista.

Ao olhar 2 níveis acima, o JOLT preserva o agrupamento original de cada produto ao formar a nova lista.

| (pipe)

O operador | permite fazer referência a múltiplos nomes de campo possíveis no JSON de entrada e mapear todos eles para o mesmo destino no JSON de saída.

Isso é útil quando a estrutura de entrada pode variar, mas a saída precisa permanecer consistente.

  • Uso: LHS

  • Operação: shift

Exemplo prático

  • Caso de uso: Tratar diferentes convenções de nomenclatura para o mesmo campo de cliente.

  • Objetivo: Mapear fullName ou customerName para um campo unificado name.

JSON de entrada

JSON de saída desejado

Spec de transformação

Explicação

  • "fullName|customerName" significa: se fullName ou customerName estiver presente, seu valor será atribuído a customer.name.

  • "email": "customer.&" preserva o nome do campo e mapeia o valor de email como está.

Isso garante que a saída permaneça consistente mesmo quando a entrada usa diferentes convenções de nomenclatura.

Continue aprendendo

Agora que você entende como esse operador funciona, aqui estão alguns próximos passos que você pode explorar:

Atualizado

Isto foi útil?