API e automatização

Null, vazio, zero ou campo ausente: como evitar mudanças de significado em JSON para uma API

Diferencie os valores de um payload JSON e consulte o contrato da API antes de decidir como transformar ou enviar cada um.

Apification
Exemplo visual de um payload JSON que compara null, uma string vazia, o número zero e uma propriedade ausente

Quatro representações distintas

Em um objeto JSON, null, "", 0 e uma propriedade omitida são representações distintas. null é um valor especial de JSON; a documentação da IBM indica que ele pode ser usado com campos de diferentes tipos, incluindo matrizes, objetos e tipos numéricos ([IBM: Como lidar com matrizes e objetos JSON nulos e vazios](https://www.ibm.com/docs/es/baw/25.0.x?topic=format-handling-json-null-empty-arrays-objects)). "" é uma string vazia e 0 é um número. Uma propriedade ausente significa que a chave não aparece no objeto. Por isso, descrever qualquer um desses casos simplesmente como “vazio” pode ocultar uma diferença importante ao revisar ou transformar dados.

Por exemplo, estes objetos não contêm a mesma representação: {"nota": null}, {"nota": ""}, {"nota": 0} e {}. No último objeto, a chave nota não é enviada; nos três primeiros, ela aparece, embora com valores diferentes. O exemplo permite comparar a forma do payload, mas não determina o que uma API fará com cada variante.

As diferenças do payload, por si só, não determinam o resultado de uma operação. Não há aqui uma regra universal para interpretar uma propriedade omitida, null, uma string vazia ou zero, especialmente ao atualizar um recurso. O contrato do endpoint específico deve esclarecer o que se espera e como esses casos são interpretados. Não convém deduzir a intenção do usuário nem a operação que o serviço realizará com base apenas no valor isolado.

Separar primeiro as representações ajuda a formular perguntas precisas: o dado não foi fornecido? Foi fornecida uma resposta em branco? O zero foi indicado explicitamente? Essas perguntas descrevem possíveis intenções, não uma semântica automática do JSON. A correspondência entre intenção, representação e resultado deve ser confirmada para o campo e a operação em questão.

  • null: valor JSON explícito.
  • "": string vazia explícita.
  • 0: número explícito.
  • Propriedade ausente: a chave não está incluída no objeto.
Quatro representações distintas

Confirme o significado no contrato da API

Para cada propriedade, consulte a documentação do endpoint e anote qual tipo ela aceita, se é obrigatória e se admite null. Em caso de atualização, procure também o que o contrato especifica sobre uma propriedade omitida, uma propriedade enviada como null e uma string vazia. Não aplique automaticamente a regra de outra operação ou de outro campo: mesmo que duas propriedades tenham nomes ou usos parecidos, a documentação a consultar é a da operação específica.

Convém distinguir as perguntas respondidas pelo contrato dos assuntos que continuam pendentes. Se a documentação disser apenas que um campo é uma string, isso não esclarece necessariamente o que significa omiti-lo ou enviar uma string vazia. Se ela mostrar apenas um exemplo com um valor numérico, isso não confirma, por si só, o que acontece com zero. Registre essas dúvidas em vez de preencher as lacunas com suposições; solicite uma confirmação ou proponha um teste controlado, quando possível.

Verifique também se o tipo do dado de origem é o esperado. Por exemplo, "0042" é uma string tal como está escrita, enquanto 42 é um número; não os converta em equivalentes sem uma regra confirmada. Se o zero inicial for removido, a representação enviada muda. A decisão de preservá-lo, transformá-lo ou tratá-lo de outra forma deve vir do requisito acordado e do contrato, não de uma conversão automática que não foi revisada.

No .NET, a Microsoft Learn explica como configurar o System.Text.Json para respeitar as anotações de nulabilidade durante a serialização e a desserialização ([Microsoft Learn: Respeitar anotações de valores nulos](https://learn.microsoft.com/es-es/dotnet/standard/serialization/system-text-json/nullable-annotations)). Essa referência trata da configuração do .NET; por si só, ela não estabelece como a API de destino interpretará o valor. Manter esses dois níveis separados evita confundir a maneira como um dado é tratado no código com o significado que o serviço documenta para o payload.

  • Registre por propriedade o tipo esperado, se ela é obrigatória e as regras documentadas para null e para a omissão.
  • Marque como pendente qualquer comportamento que o contrato não defina; não o substitua por uma suposição.
Confirme o significado no contrato da API

Documente o mapeamento antes de transformar os dados

Como prática geral de integração, crie uma tabela que relacione o estado recebido à intenção de negócio e à saída JSON prevista. Para um campo de comentário, por exemplo, registre separadamente uma resposta não fornecida e uma resposta em branco. Para uma quantidade, diferencie uma entrada vazia do número 0. A tabela não deve impor uma conversão universal: siga as regras confirmadas para essa API e deixe claro o que ainda não foi definido.

Uma linha pode descrever o dado tal como chega, sem decidir automaticamente o que será enviado. Por exemplo: campo de origem “comentário”; estado recebido “sem resposta”; intenção “a confirmar”; regra documentada “não especificada”; saída “não definida”. Outra linha pode registrar uma string vazia e uma terceira, uma resposta escrita. Assim, quem revisar o mapeamento poderá identificar quais decisões ainda faltam antes de o fluxo transformar os valores.

Deixe explícita a diferença entre preservar um dado existente, apagá-lo e atribuir zero quando essas intenções forem relevantes para o fluxo. Esses termos podem descrever objetivos distintos, mas não determinam qual representação JSON corresponde a cada um. Se o contrato definir a saída adequada, registre-a; caso contrário, indique a limitação e combine uma alternativa antes de automatizar.

Mantenha o mapeamento vinculado ao campo e ao endpoint para o qual foi documentado. Uma regra registrada para uma propriedade não deve ser reutilizada em outra sem confirmação. Também é útil manter exemplos de entrada e saída junto da regra, pois eles mostram se uma transformação altera o tipo, omite uma chave ou envia um valor explícito.

  • Modelo prático: campo de origem | estado recebido | intenção | regra documentada | propriedade e valor enviados.
  • Inclua exemplos concretos da origem para que outras pessoas possam revisar o mapeamento.
  • Separe as decisões confirmadas das perguntas pendentes.

Teste casos representativos

Como recomendação de trabalho, prepare exemplos pequenos que cubram os estados pertinentes a cada campo. Para um comentário, você poderia comparar um objeto com "comentario": null, outro com "comentario": "" e outro sem a chave. Para uma quantidade, teste null, 0 ou a omissão somente se o contrato permitir esses casos. Inclua também um valor habitual para verificar o fluxo normal. Esses exemplos servem para revisar qual payload é construído; não substituem a explicação do contrato nem permitem presumir um efeito que não foi documentado.

Anote para cada exemplo qual é a saída esperada e por que ela é considerada correta segundo a regra acordada. Se não for possível justificar essa expectativa porque o contrato não esclarece o caso, classifique-o como pendente em vez de inventar uma expectativa. Essa separação facilita a revisão do exercício: uma divergência pode decorrer de uma transformação do dado ou da falta de uma decisão sobre o significado do caso.

Revise também os valores que uma transformação poderia modificar, como uma string com espaços ou um identificador com zeros à esquerda. Decida explicitamente se eles serão preservados ou transformados, de acordo com o requisito acordado. Mantenha strings como "0042" diferenciadas de números como 42, a menos que uma regra confirmada indique o contrário. O exemplo não estabelece que um formato seja sempre correto; ele incentiva a verificar se o formato gerado corresponde ao esperado.

Compare o payload gerado com o esperado e revise a resposta da API. O fato de o JSON estar bem formado não demonstra, por si só, que ele está de acordo com o contrato ou que produzirá o efeito desejado. Se o resultado observado não corresponder ao acordado, identifique qual representação foi enviada e qual regra foi usada antes de alterar a transformação.

  • Inclua os casos normal, vazio, null, zero e propriedade omitida quando forem pertinentes ao campo e permitidos.
  • Mantenha strings, como "0042", diferenciadas de números, como 42, a menos que uma regra confirmada indique o contrário.
  • Para cada caso, anote a saída esperada ou deixe claro que a interpretação continua pendente.

Valide as alterações e mantenha um histórico útil

Como lista de verificação geral, revise a sintaxe JSON, os nomes e tipos das propriedades e as regras documentadas do endpoint. São aspectos distintos: um payload pode ser um JSON válido sem estar de acordo com o contrato. Antes de ampliar um envio automatizado, compare as saídas dos casos preparados com as esperadas e revise as respostas recebidas. O objetivo dessas verificações é detectar diferenças entre o que foi acordado e o que realmente é construído ou recebido, sem atribuir a uma resposta um significado que o contrato não define.

Quando o mapeamento ou a definição do endpoint mudar, revise novamente os exemplos pertinentes e registre qual regra foi alterada. Mantenha uma descrição breve do caso, do valor enviado, da saída esperada e do resultado observado, com o nível de detalhe necessário para compreender a revisão. Não transforme esse registro em uma fonte alternativa de semântica: se uma observação contradisser o que está documentado ou não for compreendida, consulte o contrato e esclareça a regra.

Ao investigar uma divergência, acompanhe o dado desde seu estado de origem até a representação JSON final. Verifique se a chave foi incluída, qual valor foi enviado e qual é o tipo dele, e compare o resultado com o mapeamento acordado. Essa revisão ajuda a localizar em que ponto os exemplos se desviam, sem presumir que null, uma string vazia, zero e a omissão sejam intercambiáveis.

Estas são recomendações gerais de trabalho; elas não definem o comportamento de uma API específica. A decisão final sobre uma propriedade deve se basear no contrato do endpoint. Se o contrato não resolver um caso necessário, deixe a automação desse caso pendente até obter uma interpretação confirmada.

  • Lista de verificação: contrato consultado, mapeamento documentado, casos pertinentes testados e respostas revisadas.
  • Se o resultado observado não corresponder ao esperado, pause a automação até esclarecer e corrigir a regra.

Perguntas frequentes

null e uma string vazia significam a mesma coisa em JSON?

Não são a mesma representação: null é um valor especial de JSON e "" é uma string vazia. O fato de uma API atribuir o mesmo efeito a ambos depende do contrato específico.

Posso converter qualquer campo vazio em zero?

Não faça isso sem confirmar que zero representa a intenção adequada e que o campo aceita um número. Uma entrada vazia e o número 0 são estados distintos.

O que significa omitir uma propriedade ao atualizar um recurso?

Não há uma regra universal para todas as APIs. Consulte o contrato do endpoint para descobrir como ele trata uma propriedade omitida.

Fontes e leituras

Documentação consultada para preparar este artigo.

Explore Apification

Artigos relacionados

Voltar ao blog