O que há de errado com um terminal que retorna HTML em vez de dados JSON?


77

Quando comecei a aprender PHP (há cerca de 5 ou 6 anos), aprendi sobre o Ajax e passei pelas "fases":

  1. Seu servidor retorna dados HTML e você os coloca dentro do innerHTML de um DOM
  2. Você aprende sobre os formatos de transferência de dados como XML (e diz "oooh, então é para isso que é usado) e depois o JSON.
  3. Você retorna JSON e constrói sua interface do usuário usando o código JavaScript baunilha
  4. Você muda para o jQuery
  5. Você aprende sobre APIs, cabeçalhos, códigos de status HTTP, REST , CORS e Bootstrap
  6. Você aprende as estruturas de SPA e de front-end ( React , Vue.js e AngularJS ) e o padrão da API JSON.
  7. Você recebe algum código legado da empresa e, ao inspecioná-lo, descobre que eles fazem o que é descrito na etapa 1.

Enquanto trabalhava com essa base de código herdada, nem pensei em retornar HTML (quero dizer, somos profissionais agora, certo?), Por isso tive dificuldade em procurar o ponto de extremidade JSON que estava retornando os dados que as chamadas do Ajax são preenchidas. Foi só quando perguntei ao "programador" que ele me disse que estava retornando HTML e sendo anexado diretamente ao DOM com innerHTML.

Claro, isso era difícil de aceitar. Comecei a pensar em maneiras de refatorar isso nos pontos de extremidade JSON, pensando em testar a unidade dos pontos de extremidade e assim por diante. No entanto, essa base de código não possui testes. Nem um único. E são mais de 200 mil linhas. É claro que uma das minhas tarefas inclui propor abordagens para testar a coisa toda, mas no momento não estamos resolvendo isso ainda.

Portanto, não estou em nenhum lugar, em um canto, me perguntando: se não temos nenhum teste, não temos razão específica para criar esse ponto de extremidade JSON (já que não é "reutilizável": ele literalmente retorna dados que se encaixam apenas nessa parte do aplicação, mas acho que isso já estava implícito, pois ... retorna dados HTML).

O que exatamente há de errado em fazer isso?



3
Também relacionado: stackoverflow.com/questions/1284381/… <- Uma resposta muito boa no SO.
Machado

73
Um servidor usando o HyperText Transfer Protocol retornando HyperText ?! O horror!
21417 Andy

3
@ Andy Para ser sincero, é realmente o Generic Message Transfer Protocol: nada sobre isso é específico para a transferência de hipertexto, ao contrário do FTP, que fala muito sobre coisas específicas para arquivos e diretórios.
Joker_vD 15/03

4
@Joker_vD Eu nunca ouvi falar de um protocolo chamado GMTP. Embora as coisas tenham evoluído e você possa enviar outros tipos de conteúdo por HTTP, essa não era a intenção original. O que quero dizer é que, apenas porque você pode enviar outro conteúdo além do HyperText usando HTTP, parece bobagem sugerir que não é mais válido usá-lo para sua finalidade original.
21417 Andy As

Respostas:


114

O que há de errado com um terminal que retorna HTML em vez de dados JSON?

Nada realmente. Cada aplicativo possui requisitos diferentes e pode ser que ele não tenha sido projetado para ser um SPA.

Pode ser que essas belas estruturas que você citou (Angular, Vue, React, etc ...) não estivessem disponíveis no momento do desenvolvimento ou que não fossem coisas de empresa "aprovadas" para serem usadas em sua organização.

Vou lhe dizer o seguinte: um terminal que retorna HTML reduz sua dependência das bibliotecas JavaScript e reduz a carga no navegador do usuário, pois não precisa interpretar / executar o código JS para criar objetos DOM - o HTML já está lá, é apenas uma questão de analisar os elementos e renderizá-los. Obviamente, isso significa que estamos falando de uma quantidade razoável de dados. 10 megabytes de dados HTML não são razoáveis.

Mas como não há nada de errado em retornar HTML, o que você está perdendo por não usar JSON / XML é basicamente a possibilidade de usar seu terminal como uma API. E aqui está a maior questão: ele realmente precisa ser uma API?

Relacionado: É bom retornar HTML de uma API JSON?


4
Eu daria um passo atrás antes de dizer que é apenas "simplesmente preferência". Existem algumas decisões importantes que você precisa tomar: é uma API ou não, eu tenho as bibliotecas adequadas para trabalhar com isso como dados JSON no cliente, que tipo de cliente suportarei (navegadores sem Javascript, por exemplo), o volume de vs. tempo de CPU que tem disponível para usar, qual estratégia meus programadores irá alavancar melhor, etc. etc. etc.
Machado

7
“Não será necessário interpretar o código JS para criar objetos DOM - os objetos DOM já estão lá, é apenas uma questão de renderizá-los” - bem, o HTML já está lá (depois de chegar ao ar). O navegador precisa analisar o HTML e criar os objetos DOM a partir dele.
Paul D. Waite

7
Não há razão para que o HTML não possa atuar como uma API. Zero. Nenhum. De fato, HAL + JSON e HAL + XML têm uma semelhança impressionante com o HTML. Aqui está uma excelente conversa sobre o REST. A parte relevante sobre o retorno de HTML de um ponto de extremidade está próxima do fim. youtu.be/pspy1H6A3FM Pessoalmente, faço com que todos os meus pontos de extremidade retornem json e HTML. Se você está escrevendo serviços detectáveis, fica muito fácil procurar no ... suspiro ... no navegador.
precisa

4
Porque é uma droga total extrair os dados com os quais você realmente se importa em tentar usá-los de alguma maneira nova?
23917 DeadMG

4
Servindo HTML sobre HTTP? O que é isso? Um website?
Ant P

50

JSON e HTML cumprem dois propósitos semânticos diferentes.

Se você estiver preenchendo uma página da web com dados, use JSON. Se você estiver criando uma página da Web a partir de partes de páginas da Web, use HTML.

Eles podem parecer que são a mesma coisa, mas não são. Por um lado, quando você cria uma parte de uma página da Web usando HTML retornado pelo servidor, está trabalhando no lado do servidor. Ao vincular dados a uma página da web, você trabalha no lado do cliente.

Além disso, você deve ter cuidado com o HTML para não vincular firmemente a uma página específica. O objetivo de renderizar páginas parciais dessa maneira é que as parciais sejam reutilizáveis e , se você tornar a parcial muito específica, ela não será composta por outras páginas. O JSON não tem esse problema, porque são apenas dados, não a estrutura da página da web.


1
"Por um lado, quando você cria uma parte de uma página da web usando HTML, está trabalhando no lado do servidor." Por quê? Não vejo razão para que isso aconteça. Obviamente, isso é verdade para o carregamento inicial da página e, sem dúvida, até mesmo porque o cliente pode fazer solicitações dos dados necessários.
23417 DeadMG

3
@DeadMG Deve dizer "quando você está construindo-se uma parte de uma página web usando HTML retornado pelo servidor" (em vez de usar JSON retornado pelo servidor)
user253751

De fato, mas como há pouca motivação para que isso aconteça, não vejo o ponto.
23417 DeadMG

6
@DeadMG Pouca motivação para o que sempre será o caso? Para o servidor retornar HTML? É literalmente disso que trata toda essa questão SE.
user253751

A questão é se você deve ou não retornar HTML. Está claro que a resposta inicial deve ser HTML, mas não há razão óbvia para que outras APIs retornem HTML.
23917 DeadMG

22

O principal problema é que ele acopla firmemente o servidor ao cliente, que deve conhecer a estrutura HTML. Isso também dificulta a reutilização dos pontos de extremidade de novas maneiras ou novos aplicativos.

Retornar dados simples e permitir que o cliente os processe diminui o acoplamento e aumenta a flexibilidade e a testabilidade - você pode executar testes de unidade no cliente para dados simulados e executar testes de unidade no servidor para testar os dados desejados.


11
O HTML pode ser razoavelmente genérico. Você pode retornar uma lista com marcadores, por exemplo, e colocá-la em uma div, onde ela estará sujeita a estilo pelo CSS predominante.
Robert Harvey

10
Isso não é tão útil se eu precisar colocar um pouco dessa vez. Ou renderize-o em outro aplicativo que não seja renderizado em HTML.
23917 DeadMG

2
Eu reformularia como sempre estará compondo o HTML, e a forma desse HTML sempre deve ser completamente consistente em todos os usos, o que não é uma garantia muito útil. Por exemplo, em nosso aplicativo, temos listas, mas na verdade não usamos ule, em livez disso, mudamos para tornar cada uma delas div(não lembro o porquê). Teria sido complicado se o servidor retornasse um monte de HTML com uls e lis.
23917 DeadMG

2
Parece inútil para obter a garantia, em primeiro lugar quando você pode apenas retornar os dados e deixar o cliente tornar essa como HTML como lhe aprouver (se ele está mesmo indo para torná-lo em tudo)
DeadMG

1
O único cenário que eu posso ver onde o retorno de HTML seria preferível é se o cliente não tiver recursos suficientes para fazer a renderização em si.
23917 DeadMG

14

Eu acho que você tem um pouco para trás. Você diz:

não temos nenhum teste, portanto, não temos nenhum motivo específico para criar esse terminal JSON

Um motivo para usar um terminal adequado seria para que você pudesse testá-lo. Eu diria que não ter testes é uma boa razão para começar a escrever alguns. Ou seja, se houver alguma lógica que seria adequada para testar.

É necessário refatorar muito mais de 200 mil linhas de código e provavelmente é difícil de manter. Quebrar alguns pontos de extremidade e testá-los pode ser um bom ponto de partida.

Outro motivo pode ser separar o servidor do cliente. Se, no futuro distante, o design ou o layout do aplicativo mudar, é mais fácil trabalhar com um formato de dados adequado do que a saída HTML. Em um mundo ideal, você apenas precisaria alterar o cliente e não tocar no servidor.


O ponto sobre as mudanças no layout parece mais uma necessidade de separar modelos dos dados subjacentes, mas não há razão para que esses modelos estejam no cliente. De fato, existem muitas razões para que não existam , por exemplo, você não pode decidir ocultar dados do cliente se sua renderização estiver no cliente. As parciais em HTML podem ser modificadas novamente se forem produzidas pelo mesmo sistema de modelos de páginas HTML completas.
IMSOP

6

Existem três maneiras (pelo menos?) De criar uma página da web:

  • Gere todo o lado do servidor de páginas.
  • Retorne uma página bare bones do servidor mais código (JavaScript) e faça com que a página busque seus dados e renderize no lado do cliente HTML.
  • Retorne uma página parcial mais o código e faça com que o código busque blocos pré-renderizados de HTML que possam ser inseridos na página.

O primeiro está bem. O segundo também está bem. É o último problema.

O motivo é simples: agora você dividiu a construção da página HTML em partes completamente desconectadas. O problema é de manutenção. Agora você tem duas entidades separadas encarregadas de gerenciar os detalhes da interface do usuário. Portanto, você deve manter o CSS e outros detalhes semelhantes sincronizados entre as duas partes separadas. Você mudou a largura da barra lateral? Ótimo. Agora, o fragmento HTML que retorna causa rolagem horizontal porque suas suposições sobre a largura da barra lateral não são mais válidas. Você mudou a cor de fundo desse bloco? Ótimo, agora a cor da fonte do seu fragmento HTML entra em conflito porque ela assume uma cor de fundo diferente e alguém se esqueceu de testar esse ponto de extremidade.

O ponto é que agora você dividiu o conhecimento que deve ser centralizado em um único local (a lógica da apresentação), e isso torna mais difícil garantir que todas as peças se encaixem corretamente. Ao usar uma API JSON, você pode manter toda essa lógica apenas no front-end, ou pode manter tudo isso nos seus modelos do lado do servidor, se você renderizar seus dados em HTML para começar. Trata-se de manter o conhecimento / lógica da apresentação em um único local, para que ele possa ser gerenciado de forma consistente e como parte de um único processo. HTML / CSS / JS é bastante difícil de manter em linha reta sem dividi-lo em vários pedaços minúsculos.

As APIs JSON também têm o benefício adicional de disponibilizar os dados de forma completamente independente da lógica de apresentação. Isso permite que vários apresentadores diferentes , como um aplicativo móvel e uma página da Web, consumam os mesmos dados. Em particular, ele permite consumir os dados sem um navegador (como aplicativos móveis ou tarefas cron noturnas); esses consumidores podem nem conseguir analisar o HTML. (É claro que isso depende necessariamente de uma situação em que os dados sejam os mesmos entre os diferentes consumidores ou um deles possa usar um subconjunto do outro.) Porém, se você precisa dessa capacidade depende dos requisitos de seu aplicativo em particular, enquanto gerencia sua apresentação lógica é necessária independentemente. Eu direi que, se você implementá-lo antecipadamente, estará melhor preparado para o crescimento futuro.


2
Na verdade, acho que evitar a lógica de exibição duplicada pode ser um bom motivo para renderizar fragmentos de página HTML: se você renderiza parte da página no servidor (por exemplo, o cabeçalho e o layout básico), gera outras partes com base nos dados JSON do cliente, tem dois conjuntos diferentes de modelos. A renderização de parciais no servidor move essa lógica de volta para a camada de apresentação central, que pode usar o mesmo modelo para renderizar um componente individual, como faria se estivesse montando a página inteira estaticamente.
IMSoP 15/03

1
você é o único que menciona móvel, eu quero dar-lhe mil upvotes para isso
Lovis

1
@IMSoP Se você precisar de uma página dinâmica , precisará ter lógica de front-end. Se você ainda processar os fragmentos no lado do servidor, agora precisará garantir que as suposições do front end correspondam às pré-condições do servidor que está construindo os fragmentos. Você não pode quebrar essa dependência. Manter esse conhecimento sincronizado é mais difícil se ele for dividido em sistemas completamente divididos. Se você apenas renderizar no front-end, essas suposições serão centralizadas. Eu acho que também evitaria misturar um front end dinâmico com um estado inicial em um modelo do lado do servidor; um "bootstrap" para iniciar o front end é mais simples.
jpmc26

4

Eu diria que não há nada errado com o servidor retornando um fragmento HTML e a interface do usuário atribuindo-o a .innerHTML de algum elemento. Essa é, na minha opinião, a maneira mais fácil de desenvolver código JavaScript assíncrono. O benefício é que o mínimo possível é feito usando JavaScript e o máximo possível em um ambiente de back-end controlado. Lembre-se de que o suporte a JavaScript nos navegadores varia, mas o back-end sempre tem a mesma versão dos componentes, o que significa que fazer o máximo possível no back-end significará o mínimo possível de incompatibilidades de versão.

Agora, às vezes você deseja mais do que apenas um fragmento HTML. Por exemplo, um código de status e um fragmento HTML. Em seguida, você pode usar um objeto JSON que possui dois membros, statusCode e HTML, dos quais o segundo pode ser designado a .innerHTML de algum elemento após verificar o statusCode. Portanto, usar JSON e innerHTML não são, de maneira alguma, abordagens alternativas alternativas; eles podem ser usados ​​juntos.

Ao usar JSON, você pode até ter vários fragmentos HTML na mesma resposta que são atribuídos ao .innerHTML de vários elementos.

Em resumo: use .innerHTML. Torna seu código compatível com o maior número possível de versões do navegador. Se precisar de mais, use JSON e .innerHTML juntos. Evite XML.


4

Não há nada de errado em princípio . A questão é: O que você deseja alcançar?

JSON é perfeito para transmitir dados. Se você enviar HTML e esperar que o cliente extraia os dados do HTML, isso é besteira.

Por outro lado, se você deseja transmitir o HMTL que será renderizado como HTML, envie-o como HTML - em vez de empacotar o HTML em uma sequência, transformar a sequência em JSON, transmitir JSON, decodificar do outro lado , obtendo uma sequência e extraindo o HTML da sequência.

E ontem eu encontrei um código que colocava dois itens em uma matriz, transformava a matriz em JSON, colocava o JSON em uma string, colocava a string dentro de uma matriz, transformava toda a array em JSON, enviava para o cliente, que decodificava o JSON, obteve uma matriz contendo uma sequência, pegou a sequência, extraiu o JSON da sequência, decodificou o JSON e obteve uma matriz com dois itens. Não faça isso.


+1 Exatamente. A primeira pergunta é: o que você precisa receber? Um erro de extremidade retornaria anúncios da barra lateral como um pouco de HTML, ou talvez um rodapé ou elementos semelhantes.
SQB 18/03

3

Tudo isso depende do objetivo da API, mas geralmente o que você descreve é ​​uma violação bastante forte da separação de preocupações :

Em um aplicativo moderno, o código da API deve ser responsável pelos dados e o código do cliente deve ser responsável pela apresentação.

Quando sua API retorna HTML, você está acoplando fortemente seus dados e apresentação. Quando a API retorna HTML, a única coisa que você pode fazer (facilmente) com esse HTML é exibi-lo como parte de uma página maior. De um ângulo diferente, a única coisa em que a API é boa é fornecer HTML à sua página. Além disso, você espalhou seu HTML pelo código do cliente e do servidor. Isso pode tornar a manutenção uma dor de cabeça.

Se sua API retornar JSON, ou alguma outra forma de dados puros, ela se tornará muito mais útil. O aplicativo existente ainda pode consumir esses dados e apresentá-los adequadamente. Agora, porém, outras coisas podem usar a API para acessar os mesmos dados. Mais uma vez, também, a manutenção é mais fácil - todo o HTML reside em um único local; portanto, se você deseja reformular o estilo do site inteiro, não precisa alterar sua API.


5
"Em um aplicativo moderno, o código da API deve ser responsável pelos dados e o código do cliente deve ser responsável pela apresentação." Por que esse deveria ser sempre o caso? Concordo que esse é um padrão comum e que facilita algumas coisas, mas não vejo motivo para elevá-lo ao nível de "deveria" ... É uma decisão que precisa ser tomada caso a caso, e certamente existem razões pelas quais, em algumas situações, você pode querer tomar uma decisão diferente.
Jules

@Jules, porque se você tem uma API e um cliente, ter os dois responsáveis ​​pela renderização é uma violação da separação de preocupações. (Agora, você não necessariamente tem uma API e um cliente Você pode ter apenas um componente, e tê-lo fazer toda a apresentação Mas então você não tem uma API..)
njzk2

@ njzk2 Só porque uma API entrega dados HTML não significa que os processou. Pode estar tratando o HTML como um blob e armazenando-o em um banco de dados, por exemplo. Além disso, algumas renderizações podem ser necessárias no servidor e não no cliente (por exemplo, fornecendo páginas estáticas para os mecanismos de pesquisa), de modo que a reutilização desse recurso possa ser vista como a eliminação da duplicação.
Jules

1
Além disso, é totalmente possível produzir um par de cliente e API onde toda a renderização ocorre no servidor e o cliente apenas conecta o HTML entregue aos slots predefinidos no DOM. O Jquery possui um módulo inteiro dedicado a esse tipo de cliente, o que sugere que eles devem ser razoavelmente comuns.
Jules

1
@Jules muitas coisas são razoavelmente comuns, não é por isso que são razoáveis.
Njzk2 15/03

2

O HTML está vinculado a um design e uso específicos.

Com o HTML, se você deseja alterar o layout da página, é necessário alterar a forma como o html é gerado pela chamada do servidor. Geralmente, isso requer um programador de back-end. Agora você tem programadores de back-end, que por definição não são seus melhores gravadores de html, lidando com essas atualizações.

Com o JSON, se o layout da página mudar, a chamada do servidor JSON existente não precisará necessariamente ser alterada. Em vez disso, seu desenvolvedor front-end, ou mesmo o designer, atualiza o modelo para produzir o HTML diferente desejado dos mesmos dados básicos.

Além disso, o JSON pode se tornar a base para outros serviços. Você pode ter funções diferentes que precisam ver os mesmos dados básicos de maneiras diferentes. Por exemplo, você pode ter um site do cliente que mostra dados sobre um produto em uma página de pedidos e uma página de vendas interna para representantes que mostra os mesmos dados em um layout muito diferente, talvez ao lado de outras informações não disponíveis para os clientes em geral. Com o JSON, a mesma chamada do servidor pode ser usada nas duas visualizações.

Finalmente, o JSON pode ser melhor dimensionado. Nos últimos anos, meio que exageramos nas estruturas javascript do lado do cliente. Acho que é hora de realmente dar um passo atrás e começar a pensar sobre o javascript que estamos usando e como isso afeta o desempenho do navegador ... especialmente em dispositivos móveis. Dito isto, se você estiver executando um site grande o suficiente para exigir um farm ou cluster de servidores, em vez de um único servidor, o JSON poderá ser dimensionado melhor. Os usuários concederão a você tempo de processamento em seus navegadores gratuitamente e, se você aproveitar isso, poderá reduzir a carga do servidor em uma grande implantação. JSON também usa menos largura de banda, então, novamente, se você é grande o suficientee usá-lo adequadamente, o JSON é mensurável mais barato. Obviamente, também pode ser pior, se você acabar alimentando bibliotecas de 40 KB para analisar 2 KB de dados em 7 KB de html, então novamente: vale a pena estar ciente do que está fazendo. Mas existe o potencial para o JSON melhorar o desempenho e os custos.


1

Não há nada de errado com esse terminal se ele atender aos seus requisitos. Se for necessário citar html que um consumidor conhecido possa analisar de maneira eficaz, por que não?

O problema é que, para o caso geral, você deseja que seus pontos de extremidade cuspam uma carga útil que seja bem formada e efetivamente analisável por um analisador padrão. E por efetivamente analisável, quero dizer, analisável declarativamente.

Se o seu cliente for forçado a ler a carga útil e extrair bits de informação abertos dele com loops e instruções if, ele não será efetivamente analisável. E o HTML, sendo assim, é muito perdoado por não exigir que ele seja bem formado.

Agora, se você se certificar de que seu html é compatível com xml, então você é ouro.

Com isso dito, eu tenho um problema significativo com isso:

Vou lhe dizer o seguinte: um terminal que retorna HTML reduz sua dependência das bibliotecas JavaScript e reduz a carga no navegador do usuário, pois não precisa interpretar / executar o código JS para criar objetos DOM - o HTML já está lá, é apenas uma questão de analisar os elementos e renderizá-los. Obviamente, isso significa que estamos falando de uma quantidade razoável de dados. 10 megabytes de dados HTML não são razoáveis.

Essa é uma má ideia, não importa como você a corte. Décadas de experiência industrial coletiva nos mostraram que, em geral, é uma boa idéia separar dados (ou modelo) de sua exibição (ou exibição).

Aqui você está unindo os dois para fins de rápida execução do código JS. E isso é uma micro otimização.

Eu nunca vi isso como uma boa idéia, exceto em sistemas muito triviais.

Meu conselho? Não faça isso. HC SVNT DRACONES , YMMV, etc.


0

JSON é apenas uma apresentação textual de dados estruturados. Um cliente naturalmente precisa ter um analisador para processar dados, mas praticamente todos os idiomas têm funções de analisador JSON. É muito mais eficiente usar o analisador JSON do que o HTML. É preciso pouca pegada. Não é assim com um analisador de HTML.

No PHP, você apenas usa json_encode($data)e depende do cliente do outro lado analisá-lo. E quando você busca dados JSON de um serviço da Web, basta usar $data=json_decode($response)e pode decidir como usar os dados como faria com as variáveis.

Suponha que você desenvolva um aplicativo para um dispositivo móvel. Por que você precisa do formato HTML quando aplicativos móveis raramente usam o navegador da web para analisar dados? Muitos aplicativos móveis usam JSON (formato mais comum) para trocar dados.

Considerando que os celulares geralmente usam planos medidos, por que você deseja usar HTML que ocupa muito mais largura de banda que o JSON?

Por que usar o HMTL quando o HTML é limitado em seu vocabulário e o JSON pode definir dados? {"person_name":"Jeff Doe"}é mais informativo do que o HTML pode fornecer sobre seus dados, pois define apenas a estrutura para analisadores de HTML, não define dados.

JSON não tem nada a ver com HTTP. Você pode colocar JSON em um arquivo. Você pode usá-lo para configurações. O compositor usa JSON. Você pode usá-lo para salvar variáveis ​​simples em arquivos também.


0

É difícil categorizar um certo ou errado. Na IMO, as perguntas que farei são: " deveria " ou " pode fazer com menos? ".

Todo terminal deve se esforçar para se comunicar com o mínimo de conteúdo possível. A proporção sinal / ruído é tipicamente códigos HTTP <JSON <XHTML. Na maioria das situações, é bom escolher o protocolo menos barulhento.

Eu discordo sobre o carregamento do navegador do cliente por @machado, pois nos navegadores modernos isso não é problema. A maioria deles está equipada para lidar com códigos HTTP e respostas JSON muito bem. E, embora você não tenha testes no momento, a manutenção a longo prazo de um protocolo menos barulhento seria mais barato que o acima.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.