A revolução silenciosa: como o JSON desloca o XML

Bruce Wilson Blocked Desbloquear Seguir Seguindo 11 de dezembro de 2018

Um professor de ciência da computação meu disse certa vez: “Para eu entender seu código, mostre-me seus dados.” O design dos dados é fundamental para a criação de código. Pode moldar o caráter do código. As decisões de arquitetura podem ativar uma estimativa de quanto e que tipo de dados é usado durante a execução do programa.

Embora não seja incomum em aplicativos de software ler dados de bancos de dados relacionais ou até mesmo arquivos simples com colunas de dados (CSV ou TSV), geralmente é necessária uma estrutura mais elegante para expressar relações mais complexas entre os dados. É aqui que o XML e o JSON são amplamente utilizados. O XML foi usado por muitos anos, mas gradualmente o JSON assumiu como o formato de dados escolhido em muitas aplicações.

XML e JSON possuem alguns recursos fundamentais que refletem a maneira como os dados são organizados em aplicativos de computador:

  • objetos de dados com atributos
  • hierarquia para expressar relacionamentos subordinados entre objetos de dados
  • matrizes para reunir um número possivelmente grande de objetos de dados semelhantes em um só lugar

Dados com atributos é um conceito fundamental na ciência da computação. É uma característica central da programação orientada a objetos, e antes que C e C ++ tivessem structs, Lisp tinha listas e propriedades associadas. Atributos capturam recursos de dados. Um objeto de dados representando um cliente teria detalhes como primeiro nome, sobrenome, idade, gênero, etc. Os objetos de dados com atributos também podem expressar dicionários, construções que mapeiam de um conjunto de valores de dados para outro (como um mapa de nomes de mês para números de mês, "janeiro" é 1, "fevereiro" é 2 e assim por diante). Esta é uma maneira poderosa de codificar alguma inteligência em software, definindo associações que refletem o significado entre os dados.

A hierarquia é uma maneira comum de expressar um relacionamento entre objetos relacionados. Um cliente pode ter um endereço, que por sua vez tem atributos como nome da rua, cidade, país e código de email. A hierarquia também pode envolver o agrupamento, como uma lista de pedidos de produtos pendentes para um cliente.

Os arrays fornecem uma maneira de coletar várias instâncias de dados em um único local, oferecendo a oportunidade de processar os dados em uma construção de loop simples no código. O mesmo loop programático pode processar qualquer quantidade de dados, seja 500 ou 5.000.000, e é a chave para a criação de código poderoso que pode manipular de forma flexível volumes de dados arbitrariamente grandes.

O início do XML

Em meados da década de 1990, os desenvolvedores de software começaram a usar XML para definir dados estruturados. O HTML foi usado com muito sucesso para marcar elementos de um documento da Web para especificar sua aparência. O XML usou uma notação marcada muito semelhante para especificar partes dos dados e seu significado. HTML foi projetado para ser lido e interpretado por um navegador da web. XML foi projetado para ser lido principalmente pelo software aplicativo.

Veja um exemplo de sintaxe XML, representando alguns dados sobre um cliente e seus pedidos recentes, demonstrando atributos, hierarquia e matrizes:

Dados do cliente na sintaxe XML

(O exemplo aqui está bem formatado e recuado para facilitar a leitura. Em aplicações reais, as linhas novas e a indentação provavelmente seriam removidas – os computadores ainda podem lê-la mesmo se os humanos não puderem)

O XML tornou-se amplamente popular como uma maneira de trocar dados entre o lado do cliente e do servidor nos chamados aplicativos "multicamadas" e também era comumente usado para definir o formato dos arquivos de configuração para muitos aplicativos. Padrões e ferramentas de software foram desenvolvidos para especificar, validar e manipular dados estruturados em XML. DTDs (Data Type Definitions) e posteriores XSchema para expressar a estrutura dos dados XML; XSLT para transformar dados XML de um formato para outro – cada um deles codificado em formato XML (semelhante a XML no caso de DTDs).

Mas a popularidade do XML também coincidiu com o crescimento de aplicativos B2B. O XML começou a ser usado para transmitir dados críticos de negócios entre corporações parceiras, grandes e pequenas, e empresas iniciantes como Aruba e Commerce One apareceram neste momento fornecendo plataformas e kits de ferramentas para uma troca de dados. O SOAP (“Simple Object Access Protocol”) foi introduzido como um protocolo de intercâmbio baseado em XML: um “envelope” comum de cabeçalhos XML que forneceu uma maneira de especificar endereçamento / roteamento e segurança, além da seção “payload” que transportava dados específicos do aplicativo. para ser enviado de um computador para outro. Outros padrões foram desenvolvidos para uso sob o guarda-chuva geral do “Electronic Data Interchange” (EDI) para aplicações B2B.

XML – o bom, o ruim, o feio

XML era um poderoso padrão para estruturar dados para processamento e troca de dados. Mas tinha algumas peculiaridades e limitações.

Pode ser muito detalhado. A tag principal no início de um elemento XML define o conteúdo para processamento por máquinas e para ser legível por pessoas. Quando você vê "Cliente" como o início de um elemento XML, você sabe que tipo de dados esse elemento inclui. A tag à direita melhora ligeiramente a legibilidade das pessoas, mas não adiciona nada para a legibilidade da máquina. A eliminação da tag de fechamento do elemento XML em favor de uma maneira mais simples de encerrar o conteúdo poderia reduzir consideravelmente o tamanho dos dados.

Além disso, não há representação explícita de um elemento de matriz em XML. Coleções de objetos semelhantes que foram planejados para serem processados como um grupo foram simplesmente reunidas sob um elemento comum. Mas não há indicação explícita dessa intenção nos dados XML. Uma especificação em um DTD ou XSchema poderia ser criada para definir isso, e ficaria claro ao ler o código que processa os dados que o código está fazendo em loop para processar elementos XML repetidos.

Mas o XML não oferece nenhum indicador visual de um array de dados. É possível criar um indicador desse tipo usando um elemento de quebra automática (como um elemento "& lt; orders & gt;" em torno de um grupo de elementos "& lt; order & gt;"), mas essa sintaxe não é necessária em XML.

O XML suporta namespacing, um prefixo para o nome do elemento indicando que ele pertence a um determinado grupo de tags relacionadas, provavelmente originado por uma organização separada e controlado por um esquema XML distinto. É útil para organização e validação por um computador (especialmente para particionar / classificar as partes de uma troca de dados: envelope SOAP versus carga útil, etc), mas adiciona complexidade à análise de XML, bem como a confusão visual para o leitor humano.

Depois, há um dos tópicos clássicos de debate em engenharia de software (ali mesmo com “chaves na mesma linha ou na próxima linha”): atributos ou elementos devem ser usados para propriedades de um objeto de dados ? XML deixa essa opção aberta para o implementador. Detalhes sobre um objeto Customer podem igualmente ser especificados usando atributos XML:

Propriedades dos dados do cliente especificados como atributos

… Ou usando subelementos do objeto de dados XML:

Propriedades dos dados do cliente especificados usando subelementos

Os nomes de atributos devem ser exclusivos para o elemento, não pode haver mais de um. Mas pode haver mais de um subelemento com o mesmo nome de tag em qualquer elemento específico.

Os subelementos têm uma ordem implícita que pode ser tratada como significativa pelo código de produção e consumo (sem qualquer sugestão visual). Atributos não possuem um pedido explícito.

Existe uma espécie de noção de que os atributos devem expressar um relacionamento "é-um" para o elemento XML, enquanto os subelementos expressam um relacionamento "has-a", mas, em muitos casos, a decisão é uma área cinzenta.

JSON atinge a cena

No início dos anos 2000, um formato alternativo foi proposto: JavaScript Object Notation, também conhecido como JSON. Aparecendo como parte de uma versão inicial da especificação ECMAScript, o JSON foi defendido por Douglas Crockford (autor de “Javascript: the Good Parts”). Em 2006, Crockford criou o site json.org para exaltar as virtudes do JSON, dizendo que o JSON é, “… um formato leve de troca de dados. É fácil para humanos ler e escrever. É fácil para as máquinas analisar e gerar. É baseado em um subconjunto da linguagem de programação JavaScript ”.

Veja um exemplo dos mesmos dados do cliente, formatados como JSON:

Dados do cliente na sintaxe JSON

JSON representa objetos (dicionários) e matrizes explicitamente. É inerentemente um tipo de dicionário de representação de dados. Quando uma hierarquia XML é expressa com elementos aninhados em XML, em JSON ela é expressa usando um atributo (ou na terminologia Javascript, uma propriedade) no objeto pai cujo valor é o objeto filho (observe o atributo “endereço” ou “pedidos” em o exemplo acima). As matrizes também são expressas explicitamente usando colchetes e podem conter tipos primitivos como cadeias de caracteres ou números, bem como objetos.

O JSON simplificou bastante as coisas em comparação com o formato XML. A única associação que pode ser expressa em JSON é um atributo. A hierarquia é expressa por chaves aninhadas, em que cada objeto entre chaves é associado a uma propriedade de seu pai. E não há nome ou rótulo de terminação em cada nível de hierarquia, apenas uma chave de fechamento, tornando o JSON uma maneira muito mais simples e mais sucinta do que XML de codificar uma coleção de dados.

E há um alinhamento próximo com a linguagem Javascript: JSON é essencialmente a representação de um literal de objeto Javascript, e os literais de objeto são um dos principais recursos do Javascript.

O JSON certamente cresceu como parte do crescimento do Javascript como a linguagem de desenvolvimento de software mais proeminente que é hoje. Com o surgimento de estruturas JavaScript cada vez mais sofisticadas, como Angular e React (assim como grunhido, gulp, webpack … a lista continua), a noção de desenvolvimento isomórfico tomou conta: Javascript é usado em todos os lugares. Vários livros foram escritos sobre o desenvolvimento de “MEIO” , usando MongoDB, Express, Angular e Node para todas as camadas de uma aplicação web (substitua sua escolha de framework de front-end por Angular). O JSON era uma opção natural para o formato de intercâmbio de dados entre o lado do servidor e o front end. É o formato natural no qual os dados são armazenados no MongoDB (o MongoDB é implementado em C ++, mas armazena dados em um formato semelhante ao JSON chamado BSON, serialização binária de JSON). As condições nas consultas do MongoDB são expressas usando literais de objeto Javascript e o código Javascript pode ser usado para interpretar os resultados JSON de uma consulta do MongoDB.

Analisar XML envolve o uso de uma API – algum tipo de biblioteca, escrita na linguagem de programação utilizada. O mesmo vale para o JSON, exceto em Javascript: a função JSON.parse () (suportada desde o ES6) converte JSON do formato string em objetos JavaScript nativos, matrizes e hashes. Depois que o JSON é analisado, ele pode ser percorrido como uma estrutura de dados JavaScript regular. Essa é outra maneira que o JSON contribui para tornar a programação isomorfa em Javascript uma grande vitória! Outras linguagens de desenvolvimento de software (Python, PHP, Ruby, Java) fornecem suporte à análise JSON, tornando o JSON uma maneira de trocar dados entre aplicativos escritos em diferentes idiomas.

De volta ao futuro: Precursores da representação de dados JSON

Os dados JSON parecem muito com a sintaxe literal de objeto JavaScript, provavelmente sem nenhum acidente.

Brendan Eich, o criador original do Javascript, emprestou idéias das linguagens Scheme e Self para Javascript. Scheme é um dialeto de Lisp , e a sintaxe de Lisp é “ homoicônica ” – o código e os dados são representados exatamente da mesma maneira, usando uma sintaxe parêntese aninhada muito simples. Todo o código e dados em Lisp é uma lista (como uma matriz). Os dicionários podem ser representados usando listas aninhadas.

Aqui está um exemplo dos mesmos dados do cliente representados no Lisp:

Dados do cliente na sintaxe Lisp

E aqui está uma função Lisp simples que interpreta os dados:

Uma função Lisp simples para acessar dados de clientes selecionados

… E uma demonstração de como a função e os dados funcionam juntos:

Usando a função Lisp de dados do cliente

O primeiro elemento em uma lista Lisp é significativo. No código, ele inicia um "formulário" executável (uma função), mas em dados geralmente serve como um rótulo que é de alguma forma associado com os elementos sucessivos na lista. Como demonstrado no código acima, a função “associação” procura dados testando o primeiro elemento de cada uma das sub-listas. Isso é o equivalente a uma pesquisa de dicionário em outras linguagens de programação.

Essa equivalência de dados e código foi transferida para o Javascript em grande parte. Não é apenas JSON fortemente similar (mas não bastante homoicônico) à representação de um literal de objeto Javascript, mas também é um código JavaScript passível de análise. Era comum anos atrás usar a função “eval ()” de JavaScript para avaliar e converter dados JSON em um literal de objeto.

A função eval () também é padrão em Lisp. Foi talvez a primeira linguagem de programação a usar um REPL, ou loop de leitura e impressão de eval-leitura. Hoje, é considerado um risco de segurança usar eval () em dados arbitrários enviados de uma fonte externa, mas o mais novo (e mais seguro) método JSON.parse () se ajusta ao propósito. Há também um objeto de função que fornece uma maneira de converter uma string em uma função Javascript – novamente, isso está honrando a dualidade de código e dados que começaram no Lisp e são levados adiante em Javascript hoje.

Onde estamos hoje

O JSON usa uma sintaxe mais simples para representar duas das estruturas de dados mais fundamentais no desenvolvimento de software: dicionários e matrizes. Seu estreito alinhamento com a sintaxe do Javascript torna a escolha ideal de formato de dados para muitas aplicações. A análise de dados JSON é tão simples quanto usar o JSON.parse () para convertê-lo em Javascript e, em seguida, percorrer o resultado como um objeto JavaScript regular.

É mais simples em sintaxe do que XML, elemento por elemento, consumindo menos espaço para capturar uma coleção de dados e deixando a marcação menos densa e mais facilmente legível por humanos. Os recursos do JSON, como matrizes explícitas e representação não ambígua de atributos de objetos de dados, como propriedades Javascript, promovem uma sintaxe mais simples e mais limpa.

No entanto, o XML quase não está morto e desapareceu hoje. A sindicação de sites com o RSS ainda é amplamente usada (é um recurso básico do WordPress, que alimenta um número significativo de sites atuais), e um artigo recente sugeriu que ele pode voltar ao palco. O intercâmbio eletrônico de dados (EDI) ainda é amplamente utilizado por grandes corporações. Uma notícia recente sobre o ataque ao ransomware NotPetya contou sobre a empresa de transporte internacional Maersk e como foi desativado por dias em que o EDI já não funcionaria, resultando em caminhões com contêineres alinhados em terminais de embarque e estagnados em todo o mundo.

Mas representar associações entre objetos como uma hierarquia aninhada não se encaixa em alguns domínios de aplicativo. Um exemplo são os dados de redes sociais, para os quais o GraphQL (defendido pelo Facebook e ainda usando uma representação do tipo JSON) é muitas vezes uma escolha.

RDF (uma representação baseada em XML desenvolvida pelo grupo W3C Semantic Web ) também expressa gráficos não hierárquicos de dados usando triplos “(subject, predicate, object)”, onde a parte “object” pode ser uma referência a outro triplo para definir um gráfico geral de relações entre dados. Está sendo usado em muitos projetos na web .

E o namespace originalmente usado em XML agora encontra seu caminho nos dados de tags em HTML (por exemplo, marcação semântica como os namespaces “twitter:” e “og:” na marcação de cartão do Twitter e Facebook).

Mas ainda assim, para muitos aplicativos, o JSON simplifica muito a implementação de sistemas de software baseados na Internet. É um mundo de JavaScript e o JSON desempenha um grande papel!

Plug: LogRocket , um DVR para aplicativos da web

https://logrocket.com/signup/

LogRocket é uma ferramenta de registro de front-end que permite que você repita problemas como se eles tivessem ocorrido em seu próprio navegador. Em vez de adivinhar por que os erros ocorrem ou solicitar aos usuários capturas de tela e log dumps, o LogRocket permite que você repita a sessão para entender rapidamente o que deu errado. Ele funciona perfeitamente com qualquer aplicativo, independentemente do framework, e possui plugins para registrar o contexto adicional do Redux, Vuex e @ ngrx / store.

Além de registrar as ações e o estado do Redux, o LogRocket registra logs do console, erros de JavaScript, rastreamentos de pilha, solicitações / respostas de rede com cabeçalhos + corpos, metadados do navegador e logs personalizados. Ele também instrumenta o DOM para gravar o HTML e CSS na página, recriando vídeos com pixels perfeitos até mesmo dos aplicativos de página única mais complexos.

Experimente Grátis.