Devo analisar o XML no servidor ou fornecer um proxy e permitir que o navegador o analise?

11

Preciso fazer interface com uma API de terceiros. Com essa API, faço uma solicitação GET no navegador do usuário final e recebo uma resposta XML. Esses dados devem ser usados ​​em um aplicativo baseado em navegador, onde o usuário pode pesquisá-los, usá-los para tomar decisões etc. O principal problema é que a maioria dos navegadores bloqueou o uso de XML entre domínios, por isso não posso simplesmente obter o XML da API.

Os dados gerais, no entanto, são basicamente divididos em dois conjuntos.

  1. O primeiro conjunto de dados é público e só precisa ser atualizado de tempos em tempos, para que possa ser armazenado em cache para todos os usuários no servidor, diminuindo consideravelmente o tráfego.
  2. O segundo conjunto de dados é privado e individual para cada usuário. Esses dados também são atualizados na API com mais frequência. Isso faz com que o cache seja muito menos eficaz.

Por motivos de escalabilidade, gostaria de manter a carga do servidor o menor possível.

Vejo duas opções diante de mim:

  1. Forneça um proxy que possa ser usado para rotear solicitações XML para o servidor de terceiros e diretamente entre a API do cliente e de terceiros.
  2. Faça com que o servidor faça a conversão de XML para JSON e retire informações desnecessárias. Isso significa essencialmente criar uma nova API para o nosso servidor, que se traduz em solicitações da API de terceiros

Qual seria a melhor maneira de fornecer os dados ao usuário? (Não precisa ser uma das duas opções)

amethystdragon
fonte
Qual é a relação da fonte XML com o código que a interpreta no navegador? Como se você escreveu seu próprio código de cliente (não suportado) para alimentar a partir de alguns dados de terceiros, a primeira coisa que penso é que algum dia esse terceiro fará pequenas alterações no XML e interromperá seu aplicativo para sempre.
precisa saber é o seguinte
O terceiro já atualizou sua versão da API. Eles mantiveram a versão antiga por um tempo, permitindo que as pessoas atualizassem seu código para usar a nova API. A estrutura dos dados no XML, no entanto, não mudou uma vez definida, exceto entre as versões da API.
Amethystdragon
1
Se a API mudar com frequência, provavelmente vale a pena declarar seu próprio esquema e ter um serviço que atua como middleware, manipulando os dados para algo que seu cliente espera. Acho que a pergunta se resume a 'O que é mais fácil, atualizar o cliente ou atualizar o servidor?'
precisa
Não é frequente. Ele mudou uma vez ao longo de 10 anos.
Amethystdragon

Respostas:

12

A opção de proxy é a mais fácil de implementar. Você não tem nenhum desenvolvimento personalizado para fazer, a única coisa a fazer é configurar um proxy. Também é simples: não há código adicional a ser mantido e, se a API mudar, você não precisará fazer alterações ao seu lado.

Um proxy seria a escolha preferida:

  • Se você precisar enviar o software em funcionamento rapidamente. Isso faz com que seja uma boa escolha, por exemplo, se você estava prestes a enviar um recurso, mas descobriu durante a fase de implementação do projeto que não pode apenas fazer solicitações AJAX entre domínios.

  • Ou se a API atual for bem projetada : a arquitetura é boa, as chamadas são muito claras, a documentação é completa e fácil de entender.

  • Ou se a API atual estiver sujeita a alterações. Se mudar, você só precisará alterar a implementação do JavaScript. Se, em vez de um proxy, você estiver analisando os resultados e gerando seu próprio JSON, existe o risco de que as alterações na API exijam as alterações no código do servidor.

Por outro lado, a análise do resultado tem um benefício para tornar possível abstrair completamente a API no lado do cliente. Essa é uma alternativa mais lenta, pois requer o design da nova interface (se a API original não for bem projetada) e a implementação dos recursos de extração, transformação e carregamento, mas pode ser uma boa opção a longo prazo para um projeto grande. Esta é uma escolha preferida:

  • Se você precisar de recursos adicionais. Você pode explorar os diferentes recursos que não estavam disponíveis na API original, como cache em um nível que não é suportado por um servidor proxy comum, criptografia ou outro modelo de autenticação .

    Por exemplo, se o número de solicitações AJAX se tornar um problema ou se o modelo de comunicação bidirecional fizer sentido, você poderá implementar os Web Sockets.

  • Ou se a API atual não estiver bem projetada. Como um padrão de fachada, essa abordagem permite redesenhar a API. Se o original for ruim, ter uma fachada torna possível resolver as más escolhas de design feitas pelos autores originais de uma API herdada. Você também pode agir em partes grandes, como a arquitetura geral da API, mas também em detalhes, como os nomes dos argumentos ou as mensagens de erro.

    Embora a modificação de uma API existente às vezes seja impossível, ter uma fachada pode possibilitar o trabalho com um código limpo que abstrai as desvantagens e erros no design original.

  • Ou se a API atual estiver sujeita a alterações. De fato, você pode preferir alterar o código do servidor em vez do JavaScript se a API mudar com o tempo, mantendo a interface pública da sua fachada não afetada. Pode ser mais fácil porque você tem mais experiência com programação no servidor ou conhece mais ferramentas para refatoração no servidor ou porque é mais fácil em seu projeto lidar com o controle de versão do código no servidor.

Você pode perceber que eu omiti falar sobre JSON, desempenho, cache, etc. Há uma razão para isso:

  • JSON x XML: cabe a você escolher a tecnologia certa . Você faz isso medindo objetivamente o superaquecimento de XML sobre JSON, o tempo necessário para serializar dados e a facilidade de análise.

  • Desempenho: avalie diferentes implementações, escolha a mais rápida, crie um perfil e otimize-o com base nos resultados do criador de perfil. Pare quando atingir o desempenho especificado nos requisitos não funcionais.

    Além disso, entenda o que você está tentando alcançar. Existem várias partes interagindo entre si: a API original, a largura de banda entre o servidor e a API, o desempenho do servidor, a largura de banda entre o servidor e os usuários finais e o desempenho de suas máquinas. Se você for solicitado a obter uma resposta a uma solicitação dentro de 30 ms., Mas a API original gasta 40 ms. processando a solicitação, não importa o que você faça, você não poderá obter o desempenho necessário.

  • Armazenamento em cache : o armazenamento em cache é uma das técnicas para tornar seu aplicativo Web mais rápido, reduzindo a largura de banda etc.

    1. Certifique-se de usar também o cache do cliente (o cache do servidor não reduzirá o uso da largura de banda entre você e os clientes), uma vez que a configuração adequada dos cabeçalhos HTTP geralmente é complicada.

    2. Certifique-se de determinar corretamente o que armazenar em cache, por quanto tempo e quando invalidá-lo: se a descrição do produto mudou 10 segundos atrás, mas os clientes de um site de comércio eletrônico ainda veem a versão antiga, tudo bem. Se o proprietário alterou a descrição, a enviou e ainda vê a variante anterior por causa do armazenamento em cache, isso é problemático.

    3. Não se concentre apenas no cache. A minificação, por exemplo, também é importante. Reduzir o número de solicitações também pode ser benéfico.

Arseni Mourzenko
fonte
1
+1 Hesitei um pouco sobre se devo ou não mencionar o cache e, finalmente, decidi contra. Ainda vale a pena mencionar, bom argumento.
precisa saber é
7

Há uma terceira opção que você pode não ter visto: Compartilhamento de Recursos de Origem Cruzada (CORS) .

O padrão CORS funciona adicionando novos cabeçalhos HTTP que permitem que os servidores atendam recursos a domínios de origem permitidos. Os navegadores suportam esses cabeçalhos e respeitam as restrições que estabelecem.

Exemplo : digamos que seu site seja http://my-cool-site.com e você tenha uma API de terceiros no domínio http://third-party-site.com , que você pode acessar via AJAX.

E vamos supor que uma página do servidor de my-cool-site.com feita por você solicite a third-party-site.com. Normalmente, o navegador dos usuários recusará as chamadas AJAX para qualquer outro site que não seja seu próprio domínio / subdomínio, de acordo com a Política de segurança de mesma origem . Mas se o navegador e o servidor de terceiros suportarem o CORS, as seguintes coisas acontecem:

  • O navegador enviará o seguinte cabeçalho HTTP para third-party-site.com

    Origin: http://my-cool-site.com
  • Se o servidor de terceiros aceitar solicitações do seu domínio, ele responderá com o seguinte cabeçalho HTTP:

    Access-Control-Allow-Origin: http://my-cool-site.com
  • Para permitir todos os domínios, um servidor de terceiros pode enviar este cabeçalho:

    Access-Control-Allow-Origin: *
  • Se o seu site não for permitido, o navegador emitirá um erro.

Se os clientes tiverem navegadores bastante modernos que suportam CORS e seu servidor de terceiros também suporta CORS , você pode definitivamente fazê-lo com pequenas alterações em seu código.

Encontrei uma boa explicação sobre o CORS , na qual você também encontrará outra maneira de fazer isso: JSONP . Mas o JSONP exigiria uma quantidade razoável de alterações no seu código.

Para fazer uma solicitação CORS, basta usar XMLHttpRequestno Firefox 3.5+, Safari 4+ e Chrome e XDomainRequestobjeto no IE8 +. Ao usar o XMLHttpRequestobjeto, se o navegador perceber que você está tentando fazer uma solicitação entre domínios, ele disparará perfeitamente o comportamento do CORS.

Aqui está uma função javascript que ajuda a criar um objeto CORS entre navegadores.

function createCORSRequest(method, url){
    var xhr = new XMLHttpRequest();
    if ("withCredentials" in xhr){
        // XHR has 'withCredentials' property only if it supports CORS
        xhr.open(method, url, true);
    } else if (typeof XDomainRequest != "undefined"){ // if IE use XDR
        xhr = new XDomainRequest();
        xhr.open(method, url);
    } else {
        xhr = null;
    }
    return xhr;
}

Como você diz que "a maioria dos navegadores bloqueou o uso de XML entre domínios", acho que seu servidor de terceiros pode não suportar o CORS. Então você tem que encontrar abordagens alternativas.


sampathsris
fonte
1
Você poderia tentar resumir o conteúdo nos links? As ligações são propensas a link-rot e por isso não são a melhor maneira de transmitir informações sobre SE :)
Ampt
Lamentavelmente, o servidor de terceiros não suporta o CORS.
Amethystdragon
4

Por motivos de escalabilidade, eu gostaria de manter a carga do servidor o menor possível

Eu acho que isso indica mais ou menos a resposta. O fornecimento ou não de dados pré-processados ​​ao cliente depende ou não de:

  1. a diferença em relação ao tráfego
  2. o impacto no desempenho do processamento
  3. o impacto de um formato de dados diferente no cliente

Se o XML for comparativamente pequeno ou houver apenas algumas solicitações, pode fazer sentido encaminhá-lo ao cliente e esquecê-lo. O mesmo acontece quando os dados pré-processados ​​ainda são uma grande parte dos dados originais ou se o cliente não consegue lucrar muito com um formato de dados diferente (por exemplo, JSON, por exemplo).

No entanto, se o cliente se esforçar para processar um grande conjunto de dados XML, ou se precisar de apenas uma pequena fração dos dados XML originais, pode fazer sentido fazer um pré-processamento no lado do servidor.

No final, é mais fácil dimensionar um servidor do que dimensionar um cliente / navegador ou a largura de banda disponível. Para colocar em uma frase, depende de onde o gargalo está no sistema.

JensG
fonte
+1 e adição - teste o desempenho em diferentes situações.
SeraM
0

Minha escolha seria armazenar em cache e compactar (jogar fora informações desnecessárias) e gzip para o navegador do cliente, sua opção nº 2 . Como os navegadores geralmente não são CPUs de ponta e as linhas de rede do servidor para navegador têm capacidade limitada. Estou falando de clientes móveis . Se você não planeja oferecer suporte a clientes móveis, escolha o que for mais simples, por exemplo, algunsGoogle:CORS proxy

xmojmr
fonte