Digibee Documentation
Solicitar documentaçãoAgendar demo
Português
Português
  • Primeiros passos
  • Destaques
    • Release notes
      • Release notes 2025
        • Maio
        • Abril
        • Março
        • Fevereiro
        • Janeiro
      • Release notes 2024
        • Dezembro
        • Novembro
        • Outubro
        • Setembro
        • Agosto
          • Lançamento de conectores 20/08/2024
        • Julho
        • Junho
        • Maio
        • Abril
        • Março
        • Fevereiro
        • Janeiro
      • Release notes 2023
        • Dezembro
        • Novembro
        • Outubro
        • Setembro
        • Agosto
        • Julho
        • Junho
        • Maio
        • Abril
        • Março
        • Fevereiro
        • Janeiro
      • Release notes 2022
        • Dezembro
        • Novembro
        • Outubro
        • Setembro
        • Agosto
        • Julho
        • Junho
        • Maio
        • Abril
        • Março
        • Fevereiro
        • Janeiro
      • Release notes 2021
      • Release notes 2020
    • AI Pair Programmer
    • Digibeectl
      • Comece a usar
        • Como instalar o Digibeectl no Windows
      • Digibeectl sintaxe
      • Operações do Digibeectl
  • Digibee em ação
    • Casos Práticos de Uso
      • Melhorando o desempenho de integrações com paginação de API
      • Automatize o armazenamento de arquivos com a Digibee
      • Estratégia de reprocessamento em integrações orientadas a eventos
      • Práticas essenciais para proteger informações sensíveis em pipelines com a Digibee
      • OAuth2 para acesso seguro a APIs
      • Proteja suas APIs com JWT na Digibee
      • Melhores práticas de integração para desenvolvedores na Digibee Integration Platform
      • Como usar Arquitetura orientada a eventos na Digibee Integration Platform
      • Download dinâmico de arquivos com a Digibee
      • Microsserviços: Padrão Circuit Breaker para melhorar a resiliência
      • Estratégia de tratamento de erros em integrações orientadas a eventos
    • Solução de problemas
      • Orientações para integrações
        • Como resolver problemas comuns em pipelines
        • Como resolver o Erro 409: “You cannot update a pipeline that is not on draft mode”
        • Como resolver o erro "Pipeline execution was aborted"
        • Autenticação integrada com o Microsoft Entra ID
        • Como resolver o erro "Failed to initialize pool: ONS configuration failed"
        • Como executar o mapeamento de endereços IP com o banco de dados Progress
        • Como construir fluxos de integração que enviam notificações de erro
        • Como enviar logs para serviços externos
        • Como o JSONPath difere nos conectores e no Painel de execução
        • Usando JSONPath para validar números com dígitos iniciais específicos
        • Como analisar o erro “Network error: Failed to fetch” no Painel de execução
        • Como trabalhar com requisições de payloads superiores a 5MB
        • Como configurar o Microsoft Entra ID para exibir grupos na Digibee Integration Platform
        • Como montar uma mensagem HL7
      • Comportamento e configuração de conectores
        • Timeout no conector Pipeline Executor
        • Como usar DISTINCT e COUNT no Object Store
        • Entendendo o @@DGB_TRUNCATED@@ na Digibee Integration Platform
        • Como resolver nomes sem DNS - REST, SOAP, SAP (web protocols)
        • Como ler e escrever arquivos dentro de pastas
        • AuthToken Reuse para conector Salesforce
        • Como resolver o erro "Invalid payload" na integração de API
        • Bancos de dados suportados
          • Funções e utilidades para banco de dados
      • Implementação e exemplos de uso de conectores
        • Google Storage: Cenários de uso
        • DB V2: Cenários de uso
        • For Each: Exemplo de uso
        • Template e suas utilizações
        • Implementação do Digibee JWT
        • Email V1: Exemplos de uso (Descontinuado)
      • Aplicações do JOLT
        • Transformer: Conhecendo o JOLT
        • Transformer: Transformações com JOLT
        • Transformer: Adicionar valores aos elementos da lista
        • Transformer: Visão geral das operations
        • Transformer: Formatação de datas utilizando split e concat
        • Transformer: Lógica IF-ELSE simples com JOLT
      • Dicas de acesso e desempenho da Plataforma
        • Como resolver problemas para fazer o login na Digibee Integration Platform
        • Como receber atualizações da Status Page da Digibee
        • Como executar a limpeza de cache da Digibee Integration Platform
      • Orientações sobre governança e solução de problemas
        • Como consumir pipelines com Internal API usando ZTNA
        • Como usar a API Interna com ou sem uma VPN
        • Como gerar, converter e cadastrar SSH Keys
        • Autenticação mTLS
          • Como configurar o mTLS na Digibee Integration Platform
          • Perguntas frequentes: Certificados no mTLS
        • Como conectar a Digibee ao Oracle RAC
        • Como conectar a Digibee à SAP
        • Como conectar a Digibee ao MongoDB Atlas usando VPN
        • Como gerenciar IPs na Digibee Integration Platform
        • Configurando Account Dropbox
        • Como usar sua conta do Gmail com o componente de e-mail Digibee (SMTP)
        • Como utilizar a política CORS na Digibee Integration Platform
      • Cenários de implantação
        • Como solucionar erros de “Out of memory” na implantação
        • Aviso de conflito de rotas
    • Boas práticas
      • Boas práticas para a construção de um pipeline
      • Boas práticas ao validar mensagens em um pipeline consumer
      • Evitando loops e maximizando a eficiência dos pipelines
      • Nomenclatura: Global, Contas (Accounts) e Consumers (Chaves de API)
      • Tutorial de paginação
        • Tutorial de paginação - parte 1
        • Tutorial de paginação - parte 2
        • Tutorial de paginação - parte 3
        • Tutorial de paginação - parte 4
      • Exemplos de paginação
      • Arquitetura orientada a eventos
      • Modelo de notificação em integrações orientadas a eventos
      • Modelo de integração OAuth2 com a Digibee
      • Boas práticas para tratamento de erros em pipelines
    • Digibee Academy
      • Integration Developer Bootcamp
  • Guias de referência
    • Conectores
      • AWS
        • S3 Storage
        • SQS
        • AWS Secrets Manager
        • AWS Athena
        • AWS CloudWatch
        • AWS Elastic Container Service (ECS)
        • AWS Eventbridge
        • AWS Identity and Access Management (IAM)
        • AWS Kinesis
        • AWS Kinesis Firehose
        • AWS Key Management Service (KMS)
        • AWS Lambda
        • AWS MQ
        • AWS Simple Email Service (SES)
        • AWS Simple Notification System (SNS)
        • AWS Security Token Service (STS)
        • AWS Translate
      • Azure
        • Azure CosmosDB
        • Azure Event Hubs
        • Azure Key Vault
        • Azure ServiceBus
        • Azure Storage Datalake Service
        • Azure Storage Queue Service
      • Enterprise applications
        • SAP
        • Salesforce
        • Braintree
        • Facebook
        • GitHub
        • Jira
        • ServiceNow
        • Slack
        • Telegram
        • Twillio
        • WhatsApp
        • Wordpress
        • Workday
        • Zendesk
      • File storage
        • Blob Storage (Azure)
        • Digibee Storage
        • Dropbox
        • FTP
        • Google Drive
        • Google Storage
        • OneDrive
        • SFTP
        • WebDav V2
        • WebDav (Descontinuado)
      • Files
        • Append Files
        • Avro File Reader
        • Avro File Writer
        • CSV to Excel
        • Excel
        • File Reader
        • File Writer
        • GZIP V2
        • GZIP V1 (Descontinuado)
        • Parquet File Reader
        • Parquet File Writer
        • Stream Avro File Reader
        • Stream Excel
        • Stream File Reader
        • Stream File Reader Pattern
        • Stream JSON File Reader
        • Stream Parquet File Reader
        • Stream XML File Reader
        • XML Schema Validator
        • ZIP File
        • NFS
      • Flow
        • Delayer
      • Google/GCP
        • Google BigQuery
        • Google BigQuery Standard SQL
        • Google Calendar
        • Google Cloud Functions
        • Google Mail
        • Google PubSub
        • Google Secret Manager
        • Google Sheets
      • Industry solutions
        • FHIR (Beta)
        • Gupy Public API
        • HL7
        • HubSpot: Sales e CMS
        • Mailgun API
        • Oracle NetSuite (Beta)
        • Orderful
        • Protheus: Billing e Inventory of Cost
      • Logic
        • Block Execution
        • Choice
        • Do While
        • For Each
        • Retry
        • Parallel Execution
      • Queues and messaging
        • Event Publisher
        • JMS
        • Kafka
        • RabbitMQ
      • Security
        • AES Cryptography
        • Asymmetric Cryptography
        • CMS
        • Digital Signature
        • JWT (Descontinuado)
        • JWT V2
        • Google IAP Token
        • Hash
        • Digibee JWT (Generate and Decode)
        • LDAP
        • PBE Cryptography
        • PGP
        • RSA Cryptography
        • Symmetric Cryptography
      • Structured data
        • CassandraDB
        • DB V2
        • DB V1 (Descontinuado)
        • DynamoDB
        • Google Big Table
        • Memcached
        • MongoDB
        • Object Store
        • Relationship
        • Session Management
        • Stored Procedure
        • Stream DB V3
        • Stream DB V1 (Descontinuado)
        • ArangoDb
        • Caffeine Cache
        • Caffeine LoadCache
        • Couchbase
        • CouchDB
        • Ehcache
        • InfluxDB
      • Tools
        • Assert V2
        • Assert V1 (Descontinuado)
        • Base64
        • CSV to JSON V2
        • CSV to JSON V1 (Descontinuado)
        • HL7 Message Transformer (Beta)
        • HTML to PDF
        • Transformer (JOLT) V2
        • JSLT
        • JSON String to JSON Transformer
        • JSON to JSON String Transformer
        • JSON to XML Transformer
        • JSON to CSV V2
        • JSON to CSV Transformer (Descontinuado)
        • JSON Path Transformer V2
        • JSON Path Transformer
        • JSON Transformer
        • Log
        • Pipeline Executor
        • QuickFix (Beta)
        • SSH Remote Command
        • Script (JavaScript)
        • Secure PDF
        • Store Account
        • Template Transformer
        • Throw Error
        • Transformer (JOLT)
        • Validator V1 (Descontinuado)
        • Validator V2
        • XML to JSON Transformer
        • XML Transformer
        • JSON Generator (Mock)
      • Web protocols
        • Email V2
        • Email V1 (Descontinuado)
        • REST V2
        • REST V1 (Descontinuado)
        • SOAP V3
        • SOAP V2
        • SOAP V1 (Descontinuado)
        • WGet (Download HTTP)
        • gRPC
    • Triggers
      • Web Protocols
        • API Trigger
        • Email Trigger
        • Email Trigger V2
        • HTTP Trigger
        • HTTP File Trigger
          • HTTP File Trigger - Downloads
          • HTTP File Trigger - Uploads
        • REST Trigger
      • Scheduling
        • Scheduler Trigger
      • Messaging and Events
        • Event Trigger
        • JMS Trigger
        • Kafka Trigger
        • RabbitMQ Trigger
      • Others
        • DynamoDB Streams Trigger
        • HL7 Trigger
        • Salesforce Trigger - Events
    • Double Braces
      • Como referenciar dados usando Double Braces
      • Funções Double Braces
        • Funções matemáticas
        • Funções de utilidades
        • Funções numéricas
        • Funções de string
        • Funções de JSON
        • Funções de data
        • Funções de comparação
        • Funções de arquivo
        • Funções de condição
      • Preenchimento automático de expressões Double Braces
  • Ciclo de desenvolvimento
    • Build
      • Canvas
        • Assistente de IA
        • Smart Connector User Experience
        • Painel de execução
        • Modos de Design e Inspeção
        • Linter: Validação de construção do canvas
        • Mock de Conectores
      • Pipeline
        • Como criar um pipeline
        • Como criar um pipeline usando uma especificação OpenAPI
        • Como criar um projeto
        • Histórico de versões do pipeline
        • Versionamento de pipelines
        • Processamento de mensagens
        • Subpipelines
      • Cápsulas
        • Como usar Cápsulas
          • Como criar uma coleção de Cápsulas
            • Dimensões do cabeçalho da Cápsula
          • Como criar um grupo de Cápsulas
          • Como configurar uma Cápsula
          • Como construir uma Cápsula
          • Como testar uma Cápsula
          • Como salvar uma Cápsula
          • Como publicar uma Cápsula
          • Como mudar uma Cápsula de coleção ou grupo
          • Como arquivar e restaurar uma Cápsula
        • Versionamento de Cápsulas
        • Cápsulas públicas
          • SAP
          • Digibee Tools
          • Google Sheets
          • Gupy
          • Enviar alerta por email
          • Totvs Live
          • Canvas LMS
        • Assistente de IA para geração de documentação de cápsulas
    • Run
      • Conceitos de Run
        • Autoscalling
      • Implantação
        • Implantando um pipeline
        • Como reimplantar um pipeline
        • Como promover pipelines entre ambientes
        • Como verificar o Histórico de implantação do pipeline
        • Como fazer rollback de versão implantada
        • Como utilizar as funções avançadas do histórico de implantação
        • Status de implantação do pipeline
      • Como os alertas funcionam nos pipelines em Run
    • Monitor
      • Monitor Insights (Beta)
      • Execuções concluídas
        • Download dos logs de execução de pipeline
      • Pipeline logs
      • Pipeline Metrics
        • API de métricas de pipeline
          • Como configurar API de métricas Digibee com Datadog
          • Como configurar API de métricas Digibee com Prometheus
        • Latência de Conector
      • Alertas
        • Como criar um alerta
        • Como editar um alerta
        • Como ativar, desativar ou duplicar um alerta
        • Como excluir um alerta
        • Como configurar alertas no Slack
        • Como configurar alertas no Telegram
        • Como configurar alertas via webhook
        • Métricas disponíveis
        • Boas práticas para alertas
        • Casos de uso para alertas
      • Monitoramento de conexões de VPN
        • Alertas para métricas de VPN
  • Gerenciamento de conectividade
    • Conectividade
    • Zero Trust Network Access (ZTNA)
      • Pré-requisitos para usar o ZTNA
      • Como visualizar conexões (Edge Routers)
      • Como visualizar Network Mappings associados com um Edge Router
      • Como adicionar novas conexões em ZTNA (Edge Routers)
      • Como deletar conexões em ZTNA (Edge Routers)
      • Como visualizar rotas (Network mapping)
      • Como adicionar novas rotas (Network Mapping)
      • Como adicionar rotas em lote para ZTNA
      • Como editar rotas (Network Mapping)
      • Como deletar rotas (Network Mapping)
      • Como gerar novas chaves (Edge Router)
      • Como mudar o ambiente dos Edge Routers
      • Fluxo Inverso (Inverse Flow) de ZTNA
      • Grupos de ZTNA
    • Virtual Private Network (VPN)
  • Administração da plataforma
    • Administração
      • Auditoria
      • Controle de acesso
        • Usuários
        • Grupos
        • Papéis
          • Lista de permissões por serviço
          • Papéis e responsabilidades: Governança e identificação de pessoas-chave
      • Integração com provedores de identidades
        • Como integrar um provedor de identidade
        • Regras de autenticação
        • Integração de grupos IdP com grupos Digibee
          • Como criar uma integração de grupo
          • Como testar uma integração de grupo
          • Como habilitar uma integração de grupo
          • Como editar uma integração de grupo
          • Como remover uma integração de grupo
      • Autenticação e autorização de usuários
        • Como habilitar e desabilitar a autenticação de dois fatores
        • Fluxo de login
      • Grupos da organização
    • Configurações
      • Globals
        • Como criar Globals
        • Como editar ou excluir Globals
        • Como usar Globals
      • Contas (Accounts)
        • Configurando cada tipo de conta
        • Monitore alterações nas configurações da conta em pipelines implantados
        • Arquitetura OAuth2
          • Cadastro de novos provedores OAuth
      • Consumers (Chaves de API)
      • Modelos de Relacionamento
      • Multi-Instância
        • Implantando um pipeline de multi-instância
      • Transmissão de Logs
        • Como usar a Transmissão de Logs com o Datadog
    • Governança
      • Políticas
        • Segurança
          • Política de acesso à APIs internas
          • Política de acesso à APIs externas
          • Política de campos sensíveis
        • Transformação
          • Cabeçalho HTTP personalizado
          • Cabeçalho HTTP CORS
        • Política de Limite de réplicas
    • Licenciamento
      • Modelos de licenciamento
        • Modelo baseado em consumo
      • Capacidade e cotas
      • Consumo de licenças
    • Digibee APIs
      • Como criar credenciais de API
  • Conceitos da Digibee
    • Pipeline Engine
      • Digibee Integration Platform Pipeline Engine v2
      • Suporte a Credenciais Dinâmicas (Beta Restrito)
    • SaaS dedicado na Digibee Integration Platform
      • Arquitetura da Digibee Integration Platform no modelo Saas dedicado
      • Requisitos para o modelo SaaS dedicado da Digibee
      • Site-to-Site VPN para suporte de clientes SaaS dedicado
      • Responsabilidades dos cliente Saas dedicado
      • Política de Imagens dos Nodes Kubernetes Customizados
      • Instalação do Digibee Dedicated SaaS no AWS
        • Como instalar os requisitos antes da instalação da Digibee Integration Platform no EKS
        • Permissões para usar a Digibee Integration Platform no EKS
        • Como criar nós customizados para EKS (Golden Images)
    • Introdução ao ZTNA
  • Ajuda & FAQ
    • Suporte ao Cliente Digibee
    • Solicitar documentação, sugerir nova feature ou enviar feedback
    • Programa Beta
    • Segurança e conformidade
    • Sobre a Digibee
Fornecido por GitBook
Nesta página
  • JOLT - JSON
  • Operations
  • shift
  • default
  • remove
  • sort
  • cardinality
  • Aprofundando o conhecimento
  • &
  • * (asterisco)
  • @
  • $
  • #
  • | (pipe)
  • Operations modify-default-beta e modify-overwrite-beta

Isto foi útil?

  1. Digibee em ação
  2. Solução de problemas
  3. Aplicações do JOLT

Transformer: Conhecendo o JOLT

Descubra mais sobre as transformações com JOLT e saiba como aplicá-las na Digibee Integration Platform.

AnteriorAplicações do JOLTPróximoTransformer: Transformações com JOLT

Atualizado há 3 meses

Isto foi útil?

As aplicações de Transformer (JOLT) permite transformações de JSON através do JOLT.

Para desenvolvimento e teste de todos os exemplos contidos neste artigo, .

JOLT - JSON

JSON é o formato usado por JOLT em suas transformações. Sua utilização é baseada na estrutura abaixo, sempre dependente de uma entrada:

[ 
  { 
    "operation": "", 
    "spec": { 
        
    } 
  } 
] 

Onde:

  • "operations": define o tipo da transformação que será aplicada.

  • "spec": área para aplicação da transformação.

  • "[ ]": a própria estrutura base do JOLT também é um JSON, e com isso temos um array que nos permite encadear diversas operations.

Operations

Existem diversos tipo de operations no JOLT.

  • shift

  • default

  • remove

  • sort

  • cardinality

  • modify-default-beta

  • modify-overwrite-beta

Cada operation tem sua peculiaridade e fará a transformação de maneira diferente. Entretanto, todas elas seguem o mesmo princípio para as transformações, que é a navegação na estrutura do JSON de entrada.

Abaixo veremos com mais detalhes como isso ocorre.

shift

Usado para alterar a estrutura de um JSON, mantendo os valores contidos neste mesmoarquivo JSON. Sua utilização consiste em navegar na estrutura do JSON até o campo ou objeto que desejamos pegar seu valor e em seguida informar onde esse valor deve ser colocado no novo JSON que queremos.

Vejamos o exemplo abaixo:

Temos um JSON de entrada contendo informações de Cliente:

{
  "cliente": {
    "nome": "Cliente Exemplo",
    "email": "cliente-exemplo@email.com",
    "cpf": "123.456.789.10",
    "dataNascimento": "15/02/1985",
    "endereco": "Rua do Cliente Exemplo, 123",
    "pais": "Brasil",
    "telefone": "8888-8888"
  }
}

E queremos um novo JSON com a seguinte estrutura:

{
  "customer" : {
    "name" : "Cliente Exemplo",
    "birthDate" : "15/02/1985",
    "address" : {
      "street" : "Rua do Cliente Exemplo, 123",
      "country" : "Brasil"
    },
    "phoneNumber" : "8888-8888",
    "mobileNumber" : "8888-8888"
  }
}

Nossa transformação ficará:

[ 
  { 
    "operation": "shift", 
    "spec": { 
      "cliente": { 
        "nome": "customer.name", 
        "dataNascimento": "customer.birthDate", 
        "endereco": "customer.address.street", 
        "pais": "customer.address.country",
        "telefone": ["customer.phoneNumber", "customer.mobileNumber"] 
      } 
    } 
  } 
] 

O que fizemos acima foi navegar até os campos de nosso interesse e informar onde os valores de cada um desses campos devem ser inseridos.

Através da notação "." (ponto), conseguimos definir níveis no novo JSON que queremos criar. Com isso, em "nome":"customer.name" pegamos o valor do campo nome e jogamos para o campo name dentro do objeto customer, e em "endereco":"customer.address.street" pegamos o valor do campo endereco e jogamos para o campo street dentro do objeto address que também estará contido no objeto customer.

Podemos pegar um mesmo valor de um campo e jogá-lo para mais de 1 campo ao mesmo tempo.

Em "telefone": ["customer.phoneNumber", "customer.mobileNumber"], pegamos o valor do campo telefone e jogamos para phoneNumber e mobileNumber, ambos dentro de customer. Essa abordagem nos permite transpor um único valor para n novos campos.

Nesta operation, apenas os campos manipulados na transformação serão considerados, então qualquer dado no JSON de entrada que não for utilizado será descartado.

JSON final:

{
  "customer" : {
    "name" : "Cliente Exemplo",
    "birthDate" : "15/02/1985",
    "address" : {
      "street" : "Rua do Cliente Exemplo, 123",
      "country" : "Brasil"
    },
    "phoneNumber" : "8888-8888",
    "mobileNumber" : "8888-8888"
  }
}

default

Usado para adicionar novos campos ou objetos em um JSON, caso esses não existam previamente. Sua utilização consiste em navegar na estrutura do JSON até o nível desejado e inserir o campo ou objeto com seu respectivo valor.

Caso o campo declarado na transformação já exista no JSON de entrada, a transformação não terá efeito.

Vejamos o exemplo abaixo:

Temos um JSON de entrada contendo informações de Cliente:

{
  "cliente": {
    "nome": "Cliente Default",
    "cpf": "123.456.789.10"
  }
}

Entretanto, precisamos de um JSON que além das informações de nome e cpf também contenha a data de nascimento do cliente.

{
  "cliente" : {
    "nome" : "Cliente Default",
    "cpf" : "123.456.789.10",
    "dataNascimento" : "01/01/1970"
  }
}

Nossa transformação ficará:

[
  {
    "operation": "default",
    "spec": {
      "cliente": {
        "dataNascimento": "01/01/1970"
      }
    }
  }
]

Acima nós navegamos até o objeto cliente e adicionamos o campo dataNascimento com um valor padrão.

remove

Usado para remover campos ou objetos de um JSON. Sua utilização consiste em navegar na estrutura do JSON até o nível desejado e informar o campo a ser removido.

Vejamos o exemplo abaixo:

Temos um JSON de entrada contendo informações de Cliente:

{
  "cliente" : {
    "nome" : "Cliente Default",
    "cpf" : "123.456.789.10",
    "dataNascimento" : "01/01/1970"
  }
}

Entretanto, precisamos de um JSON que contenha apenas as informações de nome e cpf do cliente:

{
  "cliente" : {
    "nome" : "Cliente Default",
    "cpf" : "123.456.789.10"
  }
}

Nossa transformação ficará:

[
  {
    "operation": "remove",
    "spec": {
      "cliente": {
        "dataNascimento": ""
      }
    }
  }
]

O que fizemos acima foi apenas navegar até o campo dataNascimento e atribuí-lo para " " (aspas vazias).

O campo a ser removido deve ser sempre atribuído à uma String vazia(""), caso contrário teremos uma quebra na transformação e a mesma não ocorrerá.

sort

Usado para ordenar campos ou objetos de um JSON em ordem alfabética.

A ordenação dos campos ou objetos não pode ser configurada, portanto todo JSON será afetado. Apenas os nomes dos campos recebem a ordenação e não seus valores.

Vejamos o exemplo abaixo:

Temos um JSON de entrada contendo informações de Funcionários:

{
  "funcionario": {
    "telefone": "9 9999-9999",
    "nome": "Cliente Sort",
    "dataNascimento": "01/01/1980",
    "cargo": "Analista JOLT"
  }
}

Precisamos que todos os campos contidos no JSON sejam ordenados em ordem alfabética:

{

  "funcionario" : {
    "cargo" : "Analista JOLT",
    "dataNascimento" : "01/01/1980",
    "nome" : "Cliente Sort",
    "telefone" : "9 9999-9999"
  }
}

Para a operation sort, não precisamos definir o objeto spec que sempre usamos junto do campo operation.

Nossa transformação será apenas:

[
  {
    "operation": "sort"
  }
]

cardinality

Usado para transformarmos campos e objetos simples em objetos listas e vice-versa.

Quando transformamos um objeto lista para um campo ou objeto simples, apenas o primeiro item da lista será considerado.

Vejamos o exemplo abaixo:

Temos um JSON de entrada contendo informações de Produtos:

{
  "produtos": {
    "nome": "Produto A",
    "id": "123-A",
    "valor": 10
  }
}

Precisamos transformar o objeto "produtos" em uma lista:

{
  "produtos" : [ {
    "nome" : "Produto A",
    "id" : "123-A",
    "valor" : 10
  } ]
}

Nossa transformação será:

[
  {
    "operation": "cardinality",
    "spec": {
      "produtos": "MANY"
    }
  }
]

Já no caso de termos uma lista de produtos:

{
  "produtos": [
    {
      "nome": "Produto A",
      "id": "123-A",
      "valor": 10
    },
    {
      "nome": "Produto B",
      "id": "456-B",
      "valor": 20
    }
  ]
}

E precisarmos transformar essa lista em um objeto simples:

{
  "produtos" : {
    "nome" : "Produto A",
    "id" : "123-A",
    "valor" : 10
  }
}

Nossa transformação ficará:

[
  {
    "operation": "cardinality",
    "spec": {
      "produtos": "ONE"
    }
  }
]

Aprofundando o conhecimento

Até aqui vimos conceitos essenciais para o entendimento e utilização do JOLT, porém antes de conhecermos as operations restantes, precisamos conhecer alguns conceitos mais elaborados.

Ainda como pré-requisito para avançarmos, veremos 2 termos que são utilizados para melhor entendimento sobre JOLT.

São eles:

  • LHS (Left Hand Side) Usado para referenciar o lado esquerdo da transformação.

  • RHS (Right Hand Side) Usado para referenciar o lado direito da transformação.

Ou seja, todo conteúdo do JSON que estiver antes dos : (dois pontos), será nosso LHS e o que estiver após os : (dois pontos), será nosso RHS.

Transformação exemplo:

[
  {
     "operation": "shift",
     "spec": {
LHS ->  "cliente": {
  LHS ->  "nome": "customer.name",  <- RHS
  LHS ->  "dataNascimento": "customer.birthDate",  <- RHS
  LHS ->  "endereco": "customer.address.street",  <- RHS
  LHS ->  "pais": "customer.address.country"  <- RHS
      }
    }
  }
]

Visto isso, agora podemos avançar.

O grande poder do JOLT está na possibilidade de lidarmos com as transformações de maneira dinâmica. Para isso, utilizamos curingas (wildcards), que são caracteres específicos alocados de diversas maneiras em nossas transformações, cada um com uma função diferente.

Um mesmo curinga pode ter funções diferentes dependendo de sua aplicação (LHS e RHS), e, além disso, podemos combinar diferentes curingas em uma mesma transformação.

Abaixo veremos suas definições e alguns exemplos de aplicações.

&

Usa o conteúdo do que está declarado no LHS para compor a estrutura do JSON de saída, sem a necessidade de explicitar este conteúdo na transformação.

Este curinga usa como base a navegação feita durante a transformação.

Uso: RHS Operations: shift

Exemplo:

Temos um JSON contendo dados de Cliente:

{
  "nome": "Cliente Exemplo",
  "email": "cliente-exemplo@email.com"
}

E precisamos desses dados em um objeto de nome "cliente" :

{
  "cliente": {
    "nome": "Cliente Exemplo",
    "email": "cliente-exemplo@email.com"
  }
}

Nossa transformação ficará:

[
  {
    "operation": "shift",
    "spec": {
      "nome": "cliente.&",
      "email": "cliente.&"
    }
  } 
]

Em &, pegamos os valores dos campos "nome" e "email", e atribuímos para outros campos chamados "nome" e "email" dentro do objeto "cliente" . Dessa forma criamos um novo JSON mantendo a estrutura dos campos do JSON de entrada.

* (asterisco)

Referencia todos os campos e objetos de um JSON sem a necessidade de explicitar seus nomes na transformação.

Uso: LHS Operations: shift, remove, cardinality, modify-default-beta e modify-overwrite-beta

Exemplo:

Temos o JSON de entrada contendo dados de Cliente:

{ 
  "nome": "Cliente Exemplo", 
  "email": "cliente-exemplo@email.com", 
  "documento": "123.456.789-10", 
  "dataNascimento": "10/05/1990", 
  "endereco": "Rua do Cliente Exemplo" 
}

E precisamos desses dados em um objeto de nome "cliente", porém precisamos alterar o campo "documento" para um campo de nome "cpf":

{ 
  "cliente": { 
    "nome": "Cliente Exemplo", 
    "email": "cliente-exemplo@email.com", 
    "cpf": "123.456.789-10", 
    "dataNascimento": "10/05/1990", 
    "endereco": "Rua do Cliente Exemplo" 
  } 
}

Nossa transformação ficará:

[
  {
    "operation": "shift",
    "spec": {
      "*": "cliente.&",
      "documento": "cliente.cpf"
    }
  }
]

Na linha "*": "cliente.&", estamos pegando qualquer conteúdo que exista no JSON de entrada e colocando em um objeto de nome "cliente" mantendo toda a estrutura de qualquer que seja esse conteúdo. Já para o campo "documento", estamos pegando seu valor e atribuindo a um campo de nome "cpf" também dentro do objeto "cliente".

O uso do curinga * junto do & faz com que para cada campo que o * encontre, o & manterá seu nome e valor. Essa utilização combinada de curingas é muito útil pois nos permite manipular um JSON sem a necessidade de conhecer e declarar seu conteúdo.

@

Referencia o valor de um campo ou objeto contido no JSON de entrada, porém possui efeitos diferentes dependendo de sua aplicação.

Uso: LHS e RHS Operations: shift (LHS e RHS), modify-default-beta (RHS) e modify-overwrite-beta (RHS).

Exemplo shift:

Temos um JSON contendo informações de Produto isoladas:

{  
    "chave": "codigo",  
    "valor": "123-ABC"
}

E precisamos agrupá-las em um objeto "produto", relacionando o campo "chave" com o campo "valor":

{  
    "produto" : {    
        "codigo" : "123-ABC"  
    }
}

Nossa transformação será:

[
  {
    "operation": "shift",
    "spec": {
      "valor": "produto.@(1,chave)"      
    }               
  }
]

Em "@(1,chave)" estamos pegando o valor do campo "chave" para ser usado como nome do campo que receberá o valor do campo "valor" ("@valor"). O uso do @ tanto no LHS quanto no RHS envolve a declaração do nível no qual estamos buscando a informação e fazemos a contagem dos níveis a partir do nível 1.

No caso o campo "chave" se encontra no mesmo nível que o campo "valor", por isso utilizamos o número 1.

A aplicação do @ no LHS segue da mesma forma que no RHS.

Exemplos modify-default-beta e modify-overwrite-beta:

Temos um JSON de entrada com dados de Produto:

{
  "produto": {
    "nome": "Produto A",
    "preco": 10
  },
  "fabricante": "Empresa A"
}

E precisamos que o objeto "produto" contenha um campo "empresa" com o valor do campo "fabricante", que está fora de "produto":

{
  "produto" : {
    "nome" : "Produto A",
    "preco" : 10,
    "empresa" : "Empresa A" 
  },
  "fabricante" : "Empresa A"
}

A transformação ficará:

[
  {
    "operation": "modify-default-beta",    //para modify-overwrite-beta
    "spec": {                              //teríamos a mesma transformação
      "produto": {                         <- nível 2  
        "empresa": "@(2,fabricante)"       <- nível 1
      }
    }
  }
]

O que fizemos foi criar um campo de nome "empresa" e atribuir nele o valor do campo "fabricante". Para isso subimos até o nível 2 para poder enxergar o campo "fabricante" e assim pegar seu valor.

A diferença entre modify-default-beta e modify-overwrite-beta é que na modify-default-beta a inclusão do campo "empresa" só é feita caso não exista outro campo de nome "empresa" dentro de "produto".

Já para a modify-overwrite-beta a inclusão do campo empresa será feita mesmo que já exista o campo "empresa" dentro de "produto". Como o próprio nome overwrite sugere, caso o conteúdo que queremos adicionar já exista no JSON de entrada, ele sempre será sobrescrito.

$

Referencia o nome de um campo ou objeto contido no JSON de entrada para ser usado como valor de um campo ou objeto no JSON de saída.

Uso: LHS Operations: shift

Exemplo:

Temos um JSON de entrada com informações de Produto:

{
  "produto": {
    "nome": "Produto Exemplo",
    "valor": 10,
    "categoria": "CATEG-1",
    "peso": 25
  }
}

E precisamos de um JSON para saber quais informações de Produto estão sendo fornecidas:

{
  "produto": [ 
    "nome",
    "valor",
    "categoria",
    "peso"
  ]
}

Nossa transformação será:

[
  {
    "operation": "shift",
    "spec": {
      "produto": {
        "*": {
          "$": "produto[]" 
        }
      }
    }
  }
]

O que fizemos foi selecionar todos (*) os campos do objeto "produto", em seguida pegar o nome ($) de cada um deles e atribuí-los a uma lista de nome "produto".

Dessa forma podemos obter o nome de cada campo e não seus valores.

#

Se usado no LHS, tem a função de inserir valores manualmente no JSON de saída.

Já no RHS, é aplicável apenas para a criação de listas e tem a função de agrupar determinado conteúdo do JSON de entrada dentro da lista a ser criada.

Uso: LHS e RHS Operations: shift

Exemplo LHS:

Temos um JSON de entrada com informações de Produto:

{
  "produto": {
    "nome": "Produto Exemplo",
    "valor": 10,
    "peso": 25
  }
}

E precisamos de um JSON que contenha informações de nome, valor, peso e categoria do produto:

{
  "produto" : {
    "categoria" : "CATEGORIA-PADRAO",
    "nome" : "Produto Exemplo",
    "valor" : 10,
    "peso" : 25
  }
}

Porém o JSON de entrada nunca fornece informações de categoria, com isso precisamos adicionar manualmente esse campo:

[
  {
    "operation": "shift",
    "spec": {
      "produto": {
        "*": "produto.&",
        "#CATEGORIA-PADRAO": "produto.categoria"
      }
    }
  }
]

O valor contido após o curinga # será sempre atribuído ao campo declarado no RHS, que no nosso caso é o campo "categoria" dentro do objeto "produto".

Exemplo RHS:

Temos um JSON de entrada contendo uma lista de Produtos:

{
  "listaProdutos": [ 
    {
      "codigo": "PROD-A", 
      "valor": 10
    },
    {
      "codigo": "PROD-B", 
      "valor": 20
    }
  ]
}

E precisamos apenas alterar o nome do campo "valor" para "preco":

{
  "produtos": [
    {
      "codigo": "PROD-A", 
      "preco": 10
    },
    {
      "codigo": "PROD-B", 
      "preco": 20
    }
  ]
}

Nossa transformação ficará:

[
  {
    "operation": "shift",
    "spec": {
      "listaProdutos": {                   <- nível 2
        "*": {                             <- nível 1   
          "codigo": "produtos[#2].&",      <- nível 0
          "valor": "produtos[#2].preco"    <- nível 0
        }
      }
    }
  }
]

O uso do # no RHS envolve a declaração do nível no qual estamos buscando a informação. A declaração [#2] representa a criação de uma lista ([ ]) e que esta deve agrupar (#) todas as informações que forem encontradas 2 níveis acima.

Precisamos dessa declaração para que seja garantido o agrupamento correto de cada produto com seu respectivo "codigo" e "preco".

Ou seja, em "codigo": "produtos[#2].&" estamos pegando o valor do campo "codigo" e jogando para outro campo "codigo" dentro de uma lista de nome "produtos", e em "valor": "produtos[#2].preco" pegamos o valor do campo "valor" e jogamos para um campo de nome "preco" dentro da mesma lista "produtos".

Porém no momento da criação da lista "produtos" olharemos 2 níveis acima (nivel da lista "listaProdutos") e da maneira que cada item estiver agrupado na "listaProdutos" anterior, esse agrupamento será mantido na nova lista "produtos".

| (pipe)

Permite referenciar múltiplos campos ou objetos de um JSON de entrada para que, independente do nome do campo ou objeto, seu valor seja alocado no mesmo destino no JSON de saída.

Uso: LHS Operations: shift

Exemplo:

Temos um JSON de entrada contendo dados de Cliente:

{
  "cliente": {
    "nomeCompleto": "Cliente Exemplo",
    "email": "cliente-exemplo@email.com"
  }
}

E precisamos de um JSON da seguinte maneira:

  {
    "cliente": {
      "nome": "Cliente Exemplo",
      "email": "cliente-exemplo@email.com"
    }
}

Entretanto, no JSON de entrada, existe a possibilidade do campo "nomeCompleto" vir com o nome "nomeCliente".Com isso precisamos que a transformação esteja preparada para reconhecer as duas possibilidades:

[
  {
    "operation": "shift",
    "spec": {
      "cliente": {
        "nomeCompleto|nomeCliente": "cliente.nome",
        "email": "cliente.&"
      }
    }
  }
]

Operations modify-default-beta e modify-overwrite-beta

Como dito na explicação do curinga @, estas operations nos permitem referenciar valores de maneira dinâmica. Enquanto a modify-default-beta atribuirá um valor a um campo caso este não exista, a modify-overwrite-beta sobrescreverá qualquer qualquer valor mesmo que o campo já exista.

Entretanto, a modify-overwrite-beta nos permite também aplicar funções em nosso JSON.

São elas:

  • String toLower, toUpper, concat, join, split, substring, trim, leftPad e rightPad

  • Number min, max, abs, avg, intSum, doubleSum, longSum, intSubtract, doubleSubtract, longSubtract, divide e divideAndRound

  • Type toInteger, toDouble, toLong, toBoolean, toString, recursivelySquashNulls, squashNulls, size

  • List firstElement, lastElement, elementAt, toList, sort

Exemplos:

JSON de entrada:

{
  "STRING": {
    "produto": "PRODUTO A",
    "empresa": "empresa a",
    "valor": "100",

    "medidaComEspacos": "  10 metros "
  },
  "NUMBER": {
    "array": [3, 5, 2, 7, 1],
    "valorNegativo": -100,
    "valorPositivo": 50
  },
  "TYPE": {
    "valor": 10.5,
    "stringBoolean": "true",
    "objetoComNulo": {
      "campoComValor": "ABC",
      "campoNulo": null
    }
  },
  "LIST": {
    "array": ["c", "t", "m", "a"],
    "campoString": "123"
  }
}

Transformações:

[
  {
    "operation": "modify-overwrite-beta",
    "spec": {
      "STRING": {
        "produto": "=toLower(@(1,produto))",
        "empresa": "=toUpper(@(1,empresa))",
        "produto_empresa": "=concat(@(1,produto),'_',@(1,empresa))",
        "joinProdutoEmpresa": "=join(' - ',@(1,produto),@(1,empresa))",
        "splitProdutoEmpresa": "=split('[-]',@(1,joinProdutoEmpresa))",
        "substringProduto": "=substring(@(1,produto),0,4)",
        "valor": "=leftPad(@(1,valor),6,'A')",
        "medida": "=trim(@(1,medidaComEspacos))"
      },
      "NUMBER": {
        "minArray": "=min(@(1,array))",
        "maxArray": "=max(@(1,array))",
        "valorAbsoluto": "=abs(@(1,valorNegativo))",
        "mediaArray": "=avg(@(1,array))",
        "somaArray": "=intSum(@(1,array))",
        "subtrArray": "=intSubtract(@(1,valorPositivo), 20)",
        "divisao": "=divide(@(1,valorPositivo),2)",
        "divisaoArred": "=divideAndRound(3,@(1,valorPositivo),3)"
      },
      "TYPE": {
        "valorInteiro": "=toInteger(@(1,valor))", 
        "booleano": "=toBoolean(@(1,stringBoolean))",
        "valorString": "=toString(@(1,valor))",
        "stringBoolean": "=size",
        "objetoComNulo": "=recursivelySquashNulls"
      },
      "LIST": {
        "arrayPrimeiroItem": "=firstElement(@(1,array))",
        "arrayUltimoItem": "=lastElement(@(1,array))",
        "arrayPosicao": "=elementAt(@(1,array),2)",
        "campoParaLista": "=toList(@(1,campoString))",
        "ordenaArray": "=sort(@(1,array))"
      }
    }
  }
]

JSON de saída:

{
  "STRING" : {
    "produto" : "produto a",
    "empresa" : "EMPRESA A",
    "valor" : "AAA100",
    "produto_empresa" : "produto a_EMPRESA A",
    "joinProdutoEmpresa" : "produto a - EMPRESA A",
    "splitProdutoEmpresa" : [ "produto a ", " EMPRESA A" ],
    "substringProduto" : "prod",
    "medida" : "10 metros"
  },
  "NUMBER" : {
    "array" : [ 3, 5, 2, 7, 1 ],
    "valorNegativo" : -100,
    "valorPositivo" : 50,
    "minArray" : 1,
    "maxArray" : 7,
    "valorAbsoluto" : 100,
    "mediaArray" : 3.6,
    "somaArray" : 18,
    "subtrArray" : 30,
    "divisao" : 25.0,
    "divisaoArred" : 16.667
  },
  "TYPE" : {
    "valor" : 10.5,
    "stringBoolean" : 4,
    "objetoComNulo" : {
      "campoComValor" : "ABC"
    },
    "valorInteiro" : 10,
    "booleano" : true,
    "valorString" : "10.5"
  },
  "LIST" : {
    "array" : [ "c", "t", "m", "a" ],
    "campoString" : "123",
    "arrayPrimeiroItem" : "c",
    "arrayUltimoItem" : "a",
    "campoParaLista" : [ "123" ],
    "ordenaArray" : [ "a", "c", "m", "t" ]
  }
}

Algumas funções não foram incluídas na transformação acima pois seguem o mesmo princípio de outras que foram inclusas, como por exemplo as funções doubleSum e longSum que são aplicadas da mesma forma que a intSum. Referente às funções recursivelySquashNulls e squashNulls, ambas são aplicáveis apenas em objetos e listas e servem para removermos campos com valores nulos, porém enquanto a recursivelySquashNulls olhará para todos os níveis abaixo do objeto ou lista, a squashNulls olhará apenas 1 nível abaixo.

A modify-overwrite-beta tem sua execução em cascata, ou seja, cada nova transformação é impactada pelas transformações anteriores.

Para entendermos esse comportamento em cascata, vamos pegar um trecho do JSON de entrada e das transformações acima:

//JSON de entrada
"STRING": {
    "produto": "PRODUTO A",
    "empresa": "empresa a",
    "valor": "100",

//Transformação
"STRING": {
        "produto": "=toLower(@(1,produto))",
        "empresa": "=toUpper(@(1,empresa))",
        "produto_empresa": "=concat(@(1,produto),'_',@(1,empresa))",

Em "produto": "=toLower(@(1,produto))" mudamos o valor de "produto" para minúsculo e em "empresa": "=toUpper(@(1,empresa))", mudamos o valor de "empresa" para maiúsculo.

Portanto no momento em que fazemos "produto_empresa": "=concat(@(1,produto),'_',@(1,empresa))", estamos utilizando os valores de "produto" e "empresa" já transformados e não seus valores originais contidos no JSON de entrada e com isso teremos "produto_empresa": "produto a_EMPRESA A".

Para uma leitura mais técnica a respeito de JOLT, .

acesse o JOLT playground
acesse a documentação sobre JOLT no GitHub