Escolhendo entre Kafka e REST? →
Mover dados entre dois bancos é só um tipo de integração. Muitos sistemas não aceitam linhas: aceitam requisições e mensagens. Um parceiro expõe um endpoint REST, uma plataforma legada publica um serviço SOAP, um serviço interno fala gRPC, um banco só aceita gravações por uma stored procedure, um pipeline interno lê de um tópico ou de uma fila. Alimentar esses sistemas costuma significar escrever um pequeno programa que lê a origem, renomeia campos, converte tipos, monta um payload e trata a resposta.
A aba Send Data cobre esse trabalho dentro do dbSlice. Ela lê registros de uma origem, mapeia para um modelo JSON com transformações por campo e entrega cada registro ao destino que você configurar. O operador vê o payload antes de qualquer coisa sair da máquina e vê como o destino respondeu depois.
Este guia segue as telas da aba Send Data, e as afirmações dele foram revisadas com a implementação do aplicativo no dbSlice 2.3. Ele explica para que serve cada passo e como fazer uma primeira entrega com cuidado. A disponibilidade pode variar conforme a versão e a licença.
1. Um registro por vez, da origem ao destino
O Send Data trata a origem como um fluxo de registros. Cada registro passa pelas mesmas quatro etapas, e a tela é organizada em volta delas.
A aba tem três passos numerados — Source, Model and mapping e Destination — e uma área comum abaixo deles, com os contadores de resultado, os botões de ação e o log de execução. New, Load e Save, no alto, permitem guardar uma configuração e reabri-la depois.
2. Escolha a origem
O primeiro passo define de onde vêm os registros.
| Origem | O que lê | Uso típico |
|---|---|---|
| Banco | Uma tabela, uma view ou um SELECT em qualquer conexão salva, com um filtro opcional e uma coluna-chave opcional para leitura paginada por chave. | Publicar dados de referência, mandar as linhas alteradas para a API de um parceiro, alimentar uma fila a partir de uma tabela operacional. |
| Arquivo JSON | Um array na raiz, um único objeto, uma coleção num caminho como data.items, ou NDJSON (um objeto JSON por linha). | Reprocessar uma exportação, repassar registros produzidos por outra ferramenta. |
| Arquivo CSV | Um arquivo de texto delimitado. Você define o delimitador, o caractere de aspas, se há cabeçalho, a codificação e o texto que significa nulo. | Carregar o extrato de uma planilha numa API que não tem importação em massa. |
Numa origem de banco, uma consulta costuma ser melhor que a tabela inteira. Escolha só as colunas de que o destino precisa e filtre as linhas no SQL. Um resultado menor e explícito é mais fácil de ver na prévia e de explicar quando alguém pergunta o que foi enviado.
Com a origem escolhida, o Read structure and sample lê até 100 registros, lista no log de execução cada campo com um tipo sugerido e um valor de amostra, e cria o mapeamento inicial. Para uma tabela de usuários de um conjunto sintético de documentação, a listagem fica assim:
id Integer 1
company_id Integer 1
permission_id Integer 1
username String demo.user.00000001
display_name String Demo User 00000001
email String user.1@example.invalid
is_active Integer 1
created_at DateTime 2023-01-01
Leia essa listagem antes de mapear qualquer coisa. Ela mostra os tipos que o dbSlice detectou, que é onde a maioria dos problemas de payload começa: uma flag guardada como inteiro, uma data que precisa de um formato específico, um código com zeros à esquerda que precisa continuar string.
3. Monte o modelo e o mapeamento
O segundo passo é uma grade com uma linha por campo do registro de saída, e uma prévia ao vivo do JSON resultante ao lado.
Model and mapping, com dados de demonstração. A prévia à direita é montada a partir do primeiro registro da amostra.
| Coluna | Para que serve |
|---|---|
| Caixa de seleção | Incluir ou deixar de fora o campo, sem apagar a linha. |
| Source field | O campo lido da origem. Uma linha sem campo de origem produz o próprio valor, com const, uuid, record ou runid. |
| Model field | O nome no JSON de saída. Um nome com pontos, como customer.id, coloca o valor dentro de um objeto aninhado. |
| Type | O tipo a produzir: String, Integer, Decimal, Boolean ou DateTime. |
| Required | Marca um campo que precisa ter valor para o registro ser válido. |
| Transforms | Uma ou mais operações aplicadas ao valor, encadeadas com |. |
| Preview | O valor depois das transformações, para o registro da amostra. |
O Map from source preenche a grade a partir dos campos da origem, o que dá um ponto de partida com uma linha por coluna. Add field e Remove ajustam a lista. O Transforms..., ou o botão … dentro de uma célula Transforms, abre o editor de transformações, onde cada passo pode ser testado com um valor de amostra.
A tela de demonstração mostra os tipos de transformação de que um payload costuma precisar:
| Transformação mostrada | Efeito no registro de demonstração |
|---|---|
trim | Tira os espaços em volta do nome. |
trim | lower | Limpa o endereço de e-mail e passa para minúsculas. |
map(Y=true;N=false) | Transforma uma flag Y/N num booleano JSON. |
number(pt-BR) | Lê um número escrito com os separadores brasileiros e emite um número JSON. |
const(customer.snapshot) | Emite um valor fixo para um campo que não tem coluna de origem, como um tipo de evento. |
São 22 transformações. São operações fixas com parâmetros; não há script nem expressão livre.
| Grupo | Transformações |
|---|---|
| Texto | trim, upper, lower, replace(from,to), substring(start,length), prefix(text), suffix(text) |
| Valores vazios e fixos | default(value), nullif(value), const(value) |
| Tabela de valores | map(A=x;B=y;*=z). Sem a entrada *, um valor desconhecido é um erro para aquele registro. |
| Números | number(culture), round(digits) |
| Datas e booleanos | date(format,culture), dateformat(format), bool |
| Proteção | mask(visible), sha256 |
| Estrutura e valores gerados | json, uuid, record, runid |
Com as linhas da tela de demonstração, a prévia do primeiro registro é:
{
"customer": {
"id": "42",
"name": "Ana Silva",
"email": "ana@example.com",
"active": true,
"balance": 1234.50
},
"eventType": "customer.snapshot"
}
As setas acima da prévia percorrem os registros da amostra. Use-as. Um mapeamento que parece certo para o primeiro registro ainda pode falhar num registro com e-mail vazio, um valor de flag inesperado ou um número em outro formato.
Design the model for the receiver. The database column names are an internal detail. Name the model fields the way the destination's contract names them, and send only what that contract asks for.
4. Escolha o destino
O terceiro passo começa pelo Destination type. O resto do formulário muda conforme o tipo escolhido.
| Tipo de destino | O que o dbSlice faz com cada registro | Opções de autenticação |
|---|---|---|
| REST API | Faz uma requisição HTTP com o método que você escolher: POST, PUT, PATCH, DELETE ou GET. | Nenhuma, basic, bearer token, API key (no cabeçalho ou como parâmetro de query), OAuth2 client credentials. |
| SOAP | Chama um web service XML (SOAP 1.1 ou 1.2). O WSDL pode ser lido para encontrar as operações. | Nenhuma, basic, bearer, WS-Security UsernameToken. O UsernameToken leva a senha como texto; então use HTTPS. |
| gRPC (unary call, .proto) | Faz uma chamada gRPC unária por registro. O modelo é codificado como a mensagem de requisição do método, lida do arquivo .proto do serviço. | Nenhuma, bearer token, basic, ou uma API key enviada como metadado da chamada. |
| Database procedure (stored procedure / function) | Chama uma stored procedure ou função uma vez por registro, numa conexão já salva no dbSlice. Cada parâmetro é alimentado por um campo do modelo. | As credenciais da própria conexão salva. |
| Apache Kafka | Publica uma mensagem num tópico. O tópico precisa já existir; o dbSlice não o cria. | Plaintext, SSL ou SASL (PLAIN, SCRAM-SHA-256, SCRAM-SHA-512), com ou sem TLS. |
| Redpanda | Publica uma mensagem num tópico. O tópico precisa já existir. | Plaintext, SSL ou SASL (PLAIN, SCRAM-SHA-256, SCRAM-SHA-512), com ou sem TLS. |
| Apache Pulsar | Publica uma mensagem num tópico. | Token JWT opcional. |
| RabbitMQ | Publica uma mensagem numa exchange com uma routing key. Uma exchange vazia envia para a fila com aquele nome. | Usuário e senha, com TLS opcional. |
As três seções a seguir descrevem os formulários de REST, gRPC e procedure de banco. A mesma origem e o mesmo modelo podem ser apontados para outro tipo de destino depois. Isso é útil quando um fluxo começa como chamada direta a uma API e mais tarde passa a ficar atrás de uma fila.
5. Configure um destino REST
O REST é o primeiro destino mais comum, e o formulário dele mostra as decisões que toda entrega envolve.
| Controle | Para que serve | Valor inicial na tela |
|---|---|---|
| URL | O endpoint que recebe cada registro. Campos do modelo podem entrar no caminho entre chaves, como em https://api.example.com/customers/{id}. | Vazio |
| Method | O método HTTP usado em todas as requisições. | POST |
| Body | record envia um registro por requisição. array envia um lote como array JSON e mostra o Batch size, de início 100. | record |
| Content type | application/json ou application/x-www-form-urlencoded. | application/json |
| Authentication | none, basic, bearer, apikey-header, apikey-query ou oauth2. | none |
| Timeout (s) | Quanto tempo esperar por cada resposta. | 30 |
| Retries | Quantas vezes uma requisição é tentada de novo, quando repeti-la é seguro. | 2 |
| Idempotency header | Nome de um cabeçalho (por exemplo Idempotency-Key) que leva uma chave por registro, enviado no POST e no PATCH. Preencha só se a API implementar isso. | Vazio |
| Allow plain HTTP | Permite uma URL http://. O localhost é sempre permitido, mesmo com a caixa desmarcada. | Desmarcado |
| HTTP headers | Cabeçalhos extras enviados em todas as requisições. Os valores podem usar campos do modelo entre chaves. | Vazio |
| Query parameters | Parâmetros acrescentados à URL. Os valores podem usar campos do modelo entre chaves. | Vazio |
Body e Content type aparecem para POST, PUT e PATCH. GET e DELETE não têm corpo; levam o registro no caminho e nos parâmetros de query.
Escolher oauth2 como autenticação acrescenta os campos do fluxo client-credentials: Token URL, Client ID, Client secret e um Scope opcional. O dbSlice pede o token e o usa nas chamadas ao endpoint.
Novas tentativas e requisições repetidas
O dbSlice só tenta de novo quando repetir é seguro. Um 429, um 503 ou uma conexão recusada sempre são repetidos. Um timeout ou um 5xx é repetido no GET, no PUT e no DELETE, que o HTTP define como repetíveis.
Um POST ou PATCH que dá timeout não é enviado de novo: o registro é contado como Unknown, porque o receptor pode tê-lo processado. Preencher o Idempotency header, quando a API implementa um, permite ao dbSlice repetir esses também, mandando a mesma chave em todas as tentativas.
6. Configure um destino gRPC
Um destino gRPC precisa do endereço do servidor e do arquivo .proto que declara o serviço. O dbSlice lê o .proto sozinho; não há etapa de compilação nem código gerado.
| Controle | Para que serve | Valor inicial na tela |
|---|---|---|
| Read proto… | Abre o arquivo .proto, lista os métodos dele (unários ou de streaming, mensagem de requisição, campos da requisição) e preenche Proto file e Method. Só um método unário pode ser escolhido. | |
| Server address | O servidor, só como esquema, host e porta: https://host:443. | Vazio |
| Proto file | O .proto que declara o serviço. Os imports são procurados ao lado dele e nas pastas acima. | Vazio |
| Method | O método a chamar, como package.Service/Method. | Vazio |
| Authentication | none, bearer, basic ou apikey-header. | none |
| Import folders | Pastas extras para os arquivos .proto importados, separadas por ;. | Vazio |
| Timeout (s) | O prazo de cada chamada. | 30 |
| Retries | Quantas vezes uma chamada é tentada de novo, quando repeti-la é seguro. | 2 |
| Allow plain HTTP | Permite um endereço sem TLS. O localhost é sempre permitido. | Desmarcado |
| Call metadata | Pares de nome e valor enviados em todas as chamadas. Os valores podem usar campos do modelo entre chaves. | Vazio |
Depois que você escolhe um método, o log lista os campos que a mensagem de requisição espera. Use esses nomes como campos do modelo. Mensagens aninhadas correspondem a campos aninhados do modelo (customer.id), listas correspondem a campos repeated, e enums aceitam o nome ou o número. Um campo do modelo que não existe na mensagem é um erro para aquele registro: nada é descartado em silêncio.
A chamada usa HTTP/2, com TLS para endereços https://.
Como os resultados do gRPC são contados
| Contador | Resultado do gRPC |
|---|---|
| Confirmed | O servidor respondeu OK. |
| Rejected | O servidor recusou a chamada: INVALID_ARGUMENT, NOT_FOUND, ALREADY_EXISTS, PERMISSION_DENIED, FAILED_PRECONDITION, ABORTED, OUT_OF_RANGE, UNIMPLEMENTED, UNAUTHENTICATED e RESOURCE_EXHAUSTED depois das novas tentativas. |
| Unknown | DEADLINE_EXCEEDED, UNAVAILABLE, INTERNAL, UNKNOWN, CANCELLED, DATA_LOSS ou um timeout. O servidor pode ter processado a chamada. |
| Not sent | Não havia conexão, ou o registro não cabe na mensagem de requisição. |
Só UNAVAILABLE, RESOURCE_EXHAUSTED e uma conexão recusada são repetidos.
7. Configure um destino de procedure de banco
Alguns bancos só aceitam gravações por stored procedures, para as regras ficarem num lugar só. Este destino chama uma procedure ou função uma vez por registro, usando uma conexão já salva no dbSlice.
| Controle | Para que serve | Valor inicial na tela |
|---|---|---|
| Connection | Uma das conexões salvas. Uma conexão marcada como somente leitura é recusada. O SQLite não está disponível, porque não tem stored procedures. | |
| Read procedures… | Lista as procedures e funções da conexão com os parâmetros e os tipos, e preenche o nome, o tipo e a grade de parâmetros. A lista é lida do catálogo; nada é executado. Disponível para SQL Server, PostgreSQL e MySQL/MariaDB. | |
| Procedure | O nome como o banco o conhece, com o esquema se for preciso: dbo.insert_leave, public.myinsert. | Vazio |
| Kind | auto, procedure ou function. O auto segue a declaração no banco. | auto |
| Procedure parameters | Uma linha por parâmetro: o nome do parâmetro e, como valor, o campo do modelo entre chaves. | Vazio |
Na grade de parâmetros, um valor vazio usa o campo do modelo com o mesmo nome do parâmetro, ignorando um _ ou @ no início. Qualquer outro texto é um modelo e é enviado como texto.
Para uma procedure declarada como dbo.insert_leave(@sno int, @eid int, @sd date, @ed date, @sid int, @status bit), a grade seria:
@sno {sno}
@eid {employee.id}
@sd {sd}
@ed {ed}
@sid {sid}
@status {status}
Como cada banco é chamado
| Banco | Chamada |
|---|---|
| SQL Server | EXEC procedure @parameter = value, por nome. Só procedures. |
| PostgreSQL | SELECT function(…) ou CALL procedure(…), com um cast para cada tipo declarado. |
| MySQL / MariaDB | CALL procedure(…) ou SELECT function(…). |
| Oracle | BEGIN procedure(…); END;. Só procedures. |
| Firebird | EXECUTE PROCEDURE procedure(…). |
| InterSystems IRIS / Caché | CALL procedure(…). |
No SQL Server, no PostgreSQL e no MySQL/MariaDB, o dbSlice lê a declaração do catálogo. Os parâmetros vão na ordem declarada, qualquer que seja a ordem da grade, e cada valor é convertido para o tipo declarado antes da chamada: um texto de data ISO vira data, e Y/N vira booleano.
Nos outros bancos, o nome e os parâmetros são digitados, a ordem da grade é a ordem da chamada, e os valores são enviados como estão.
Cada chamada é confirmada sozinha. Não há transação em volta de um grupo de registros; então uma execução que para no meio deixa gravados os registros anteriores.
Como os resultados da procedure são contados
| Contador | Resultado da procedure |
|---|---|
| Confirmed | A chamada voltou sem erro. |
| Rejected | O banco devolveu um erro: uma regra dentro da procedure, uma chave duplicada, um valor inválido. A mensagem dele vai para o log. |
| Unknown | A conexão caiu ou a chamada deu timeout. O banco pode tê-la concluído. |
| Not sent | Não havia conexão, ou um parâmetro aponta para um campo que o modelo não tem. |
8. Decida o que acontece quando um registro falha
O grupo Execution controla como uma execução se comporta quando algo dá errado.
| Controle | Para que serve | Valor inicial na tela |
|---|---|---|
| On record error | Se a execução para ou continua depois que um registro falha. | Stop at the first error |
| Stop after errors | Vale quando a execução continua depois de erros. Conta todas as falhas (inválidos, rejeitados, desconhecidos e não enviados), e a execução para quando o total passa desse número. | 100 |
| Record limit | O número máximo de registros a processar. 0 significa sem limite. | 0 |
Parar no primeiro erro é o padrão certo para um fluxo novo: a primeira falha costuma revelar um problema de mapeamento ou de contrato que se repetiria em todos os registros. Continuar faz sentido quando já se sabe que o fluxo funciona e registros ruins ocasionais são esperados.
O Record limit é um jeito simples de aumentar uma entrega em etapas: dez registros, depois mil, depois tudo.
9. Valide, teste e envie uma amostra
Três botões permitem conferir o trabalho antes de uma execução completa. Eles respondem perguntas diferentes, e vale usá-los nesta ordem.
| Botão | Pergunta que responde | Envia dados? |
|---|---|---|
| Validate and preview | Os 20 primeiros registros produzem payloads válidos com este modelo? | Não. |
| Test connection | O dbSlice alcança o destino? No REST e no SOAP, abre a conexão (e o TLS) com o host; com OAuth2, também pede um token. No Kafka, no Redpanda e no RabbitMQ, autentica e confere se o tópico ou a exchange existe. No Pulsar, conecta no broker. No gRPC, abre a conexão (e o TLS) com o servidor sem chamar o método. Numa procedure de banco, conecta e, onde o catálogo está disponível, confere se a procedure existe, sem chamá-la. Ele nunca envia um registro e não prova permissão de gravação. | Não. |
| Send sample | O destino aceita registros reais? O número ao lado do botão define quantos dos primeiros registros são enviados. | Sim, só a amostra. |
O log informa o resultado de uma validação com clareza:
Preview: 2 record(s) read, 0 with errors. Nothing was sent.
Uma amostra de poucos registros contra o destino real é o teste mais informativo. Um teste de conexão bem-sucedido não mostra que a credencial é aceita por um endpoint REST nem que a conta pode gravar. A amostra mostra: ela exercita a URL, a autenticação, o formato do payload e as regras de validação do receptor juntos, num tamanho fácil de inspecionar e de desfazer do outro lado.
10. Rode e leia o resultado
O Run pede confirmação e depois processa a origem até o limite de registros. O painel Processing status, abaixo da árvore de conexões, mostra o início, o tempo decorrido, o fim estimado e os contadores da execução, e tem o botão Cancel, que para uma execução em andamento. Os contadores resumem o que aconteceu com os registros.
| Contador | Leitura |
|---|---|
| Read | Registros lidos da origem. |
| Confirmed | Registros que o destino confirmou. |
| Invalid | Registros que falharam no mapeamento, na validação ou numa transformação. Não foram enviados. |
| Rejected | Registros que o destino respondeu recusando. |
| Unknown | Registros que foram enviados, mas não receberam confirmação: um timeout, uma conexão perdida durante o envio, ou uma execução cancelada durante um envio. Eles podem ou não ter chegado. |
| Not sent | Registros que nunca saíram da máquina: não havia conexão com o destino, ou a execução parou antes da vez deles. |
A separação importa porque cada grupo pede uma ação diferente. Os inválidos são corrigidos na origem ou no mapeamento. Os rejeitados são uma conversa com o dono do destino. Os desconhecidos são os delicados: confira o destino antes de enviá-los de novo, já que alguns podem ter chegado.
Guarde o log de execução de uma execução real. O Copy o coloca na área de transferência, para ser guardado com o registro da mudança ou o chamado que pediu a entrega.
11. O que o Send Data não promete
O Send Data entrega registros e informa o que aconteceu com cada um. Conhecer os limites dele ajuda a decidir onde ele se encaixa.
- Sem garantia de exactly-once. Um registro pode ser entregue mais de uma vez quando uma requisição repetível é tentada de novo, e uma execução que para pode deixar registros sem enviar. Prepare o lado que recebe para tolerar repetições.
- Execuções sem ninguém olhando não retomam. Uma configuração salva pode rodar como job pela tela CLI jobs ou pela linha de comando; então ela pode ser agendada. Uma execução que para não continua de onde parou: planeje a consulta de origem para que uma nova execução escolha só os registros que faltam.
- Sem integração com schema registry. As mensagens publicadas num broker levam o JSON que você modelou. Combine o formato com os consumidores.
- gRPC: só chamadas unárias. Métodos de streaming, server reflection, compressão e certificados de cliente não são suportados, e a mensagem de resposta não é lida, só o status.
- Procedure de banco: só entradas. Parâmetros de saída e conjuntos de resultados não são lidos, e os registros não são agrupados numa transação. Funções só podem ser chamadas no PostgreSQL e no MySQL/MariaDB.
Rodar uma configuração salva como job
Uma configuração salva pela aba é um arquivo *.dbsend.json. Ela roda como um job do tipo send, pelo Run now em Tools → CLI jobs ou pela linha de comando:
dbSlice --new send delivery.json
dbSlice delivery.json delivery.log
O primeiro comando cria um modelo; o segundo roda o job e grava o log dele. O código de saída é 0 no sucesso, 1 quando pelo menos um registro não foi confirmado, e 2 para um job inválido ou falta de licença. As notificações por e-mail e webhook de um job funcionam como nos outros tipos de job.
Uma entrega agendada, então, funciona, com os mesmos limites de uma manual: sem retomada e sem exactly-once. Confira o código de saída e os contadores no log, e desenhe a consulta de origem e o receptor para que rodar de novo seja seguro.
12. Credenciais, rede e licença
O Send Data só conecta nos endereços que você configura: o endpoint da API, o web service e o WSDL dele, a URL do token, o servidor gRPC, o banco da conexão salva ou o broker. Os registros vão da máquina que roda o dbSlice para esse destino.
As credenciais informadas para um destino ficam nessa máquina, protegidas para o usuário atual do Windows. O arquivo salvo não contém segredo em texto aberto, e não funciona com outra conta do Windows nem em outra máquina até o segredo ser digitado de novo. O mesmo vale para um job agendado: ele precisa rodar com o usuário do Windows que salvou a configuração.
Um destino de procedure de banco usa as credenciais da conexão salva; nada novo é guardado na configuração para ele.
Mesmo assim, trate uma configuração salva como sensível: ela documenta um endpoint e como chegar nele. Use uma credencial criada para esse fim, só com as permissões de que a entrega precisa, e prefira endpoints HTTPS.
O Send Data faz parte do dbSlice 2.3, nas edições Desktop e Server, tanto na aba quanto como job. Configurar um fluxo, validá-lo e ver a prévia dos payloads funcionam sem licença ativa. O Send sample, o Run e o job exigem licença.
Uma primeira entrega com cuidado
- Escreva uma consulta de origem que devolva só os campos e as linhas de que o destino precisa.
- Clique em Read structure and sample, leia a listagem de campos no log e confirme os tipos sugeridos.
- Renomeie os campos do modelo do mapeamento inicial para baterem com o contrato do destino.
- Acrescente transformações e percorra vários registros da amostra na prévia.
- Configure o destino primeiro contra um ambiente de teste, se houver um.
- Rode o Validate and preview e resolva todos os registros com erro.
- Rode o Test connection, lembrando o que ele confere e o que não confere no seu tipo de destino.
- Use o Send sample com um número pequeno e confira os registros do lado que recebe.
- Defina um Record limit para a primeira execução real e deixe o On record error em parar.
- Rode, leia os contadores e guarde uma cópia do log.
Escopo deste guia
Os controles, os valores iniciais e as linhas de log descritos aqui foram tirados de capturas da aba Send Data. O comportamento das origens, das transformações, dos tipos de destino, das opções de autenticação, das novas tentativas, do teste de conexão, dos contadores e dos jobs, e as observações de versão e licença, foram revisados com a implementação do aplicativo no dbSlice 2.3.
O destino gRPC foi exercitado contra um servidor de teste sem TLS. O destino de procedure de banco foi exercitado contra bancos de teste PostgreSQL, SQL Server e MariaDB; os comandos de Oracle, Firebird e InterSystems seguem a sintaxe de cada banco e não foram rodados contra esses bancos.
A listagem de campos e o payload usam dados sintéticos de demonstração. Nenhuma requisição foi enviada a uma API, web service ou broker em uso para escrever este artigo, e nenhuma taxa ou tempo de entrega é afirmado. Os nomes de conexão visíveis nas capturas originais não fazem parte da publicação.