desempenho http HEAD vs GET

111

Estou configurando um serviço web REST que só precisa responder SIM ou NÃO, o mais rápido possível.

Projetar um serviço HEAD parece a melhor maneira de fazer isso, mas eu gostaria de saber se realmente irei ganhar algum tempo em vez de fazer uma solicitação GET.

Suponho que ganhei o stream de corpo para não ser aberto / fechado no meu servidor (cerca de 1 milissegundo?). Como a quantidade de bytes a retornar é muito baixa, ganho algum tempo em transporte, em número de pacote IP?

Agradecemos antecipadamente a sua resposta!

Editar:

Para explicar melhor o contexto:

  • Eu tenho um conjunto de serviços REST executando alguns processos, se eles estiverem em um estado ativo.
  • Eu tenho outro serviço REST indicando o estado de todos esses primeiros serviços.

Uma vez que esse último serviço será chamado com muita frequência por um conjunto muito grande de clientes (uma chamada esperada a cada 5 ms), eu gostaria de saber se usar um método HEAD pode ser uma otimização valiosa. Cerca de 250 caracteres são retornados no corpo da resposta. O método HEAD ganha pelo menos o transporte desses 250 chars, mas que impacto é esse?

Tentei comparar a diferença entre os dois métodos (HEAD vs GET), executando 1000 vezes as chamadas, mas não vi nenhum ganho (<1ms) ...

Asterius
fonte
2
Também depende da abordagem que você usa no lado do servidor. Geralmente, pode levar o mesmo tempo do servidor para processar uma solicitação GET ou uma solicitação HEAD, porque o servidor pode precisar saber o corpo final para calcular o Content-Lengthvalor do cabeçalho, que é uma informação importante em uma resposta a uma solicitação HEAD. A menos que haja alguma outra abordagem mais otimizada do lado do servidor, o único benefício é que a largura de banda é salva e o cliente não precisa analisar o corpo da resposta. Então, basicamente, os ganhos de otimização dependem das implementações de servidor e cliente.
itsjavi de

Respostas:

173

Um URI RESTful deve representar um "recurso" no servidor. Os recursos são freqüentemente armazenados como um registro em um banco de dados ou um arquivo no sistema de arquivos. A menos que o recurso seja grande ou seja lento para recuperar no servidor, você pode não ver um ganho mensurável usando em HEADvez de GET. Pode ser que recuperar os metadados não seja mais rápido do que recuperar todo o recurso.

Você poderia implementar ambas as opções e compará-las para ver qual é mais rápida, mas em vez de microotimizar, eu focaria em projetar a interface REST ideal. Uma API REST limpa é geralmente mais valiosa a longo prazo do que uma API kludgey que pode ou não ser mais rápida. Não estou desencorajando o uso de HEAD, apenas sugerindo que você só use se for o design "certo".

Se as informações de que você realmente precisa são metadados sobre um recurso que pode ser representado muito bem nos cabeçalhos HTTP, ou para verificar se o recurso existe ou não, HEADpode funcionar bem.

Por exemplo, suponha que você queira verificar se o recurso 123 existe. A 200significa "sim" e a 404significa "não":

HEAD /resources/123 HTTP/1.1
[...]

HTTP/1.1 404 Not Found
[...]

No entanto, se o "sim" ou "não" que você deseja de seu serviço REST fizer parte do próprio recurso, em vez de metadados, você deve usar GET.

E vermelho
fonte
2
as melhores coisas são sempre simples, assim como esta resposta. Voila!
Afzal SH
Resposta maravilhosa! Eu tenho uma pergunta: que tal usá-lo como um touchcomando para atualizar a contagem de visualizações de uma postagem no servidor? Os dados da postagem já foram recuperados por meio de uma /postschamada normal , então eu só quero atualizar a contagem de visualizações após o usuário interagir com a postagem de alguma forma.
aalaap de
1
@aalaap Se você for atualizar um contador de visualizações para HEADsolicitações, deverá fazer isso GETtambém. A decisão de usar GETou, em HEADúltima análise, é com o cliente HTTP. Seu servidor deve se comportar da mesma maneira para os dois tipos de solicitação, exceto que não há corpo de resposta ao responder HEAD. Quanto a saber se esta é uma boa maneira de implementar algo como um contador de visualizações, não tenho certeza.
Andre D
-1 Qualquer informação que possa ser nomeada pode ser um recurso. Conseqüentemente, Uniform Resource Locator. A ideia de que usar parte do protocolo HTTP, conforme projetado, é "kludgey" ou "impuro" é bizarra.
Fraser de
1
@Siddhartha, isso muitas vezes é verdade, mas nem sempre. Content-Lengthpode ser omitido ao usar Transfer-Encoding: chunked. Mesmo com Content-Length, é possível que o servidor possa obter o tamanho do recurso e outros metadados usados ​​nos cabeçalhos sem buscar o recurso real. Talvez esses metadados sejam até mesmo armazenados em cache na memória para acesso muito rápido. Isso tudo é muito específico de implementação.
Andre D
38

Encontrei esta resposta ao procurar a mesma pergunta que o solicitante fez. Eu também encontrei isso em http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html :

O método HEAD é idêntico ao GET, exceto que o servidor NÃO DEVE retornar um corpo de mensagem na resposta. A metainformação contida nos cabeçalhos HTTP em resposta a uma solicitação HEAD DEVE ser idêntica à informação enviada em resposta a uma solicitação GET. Este método pode ser usado para obter metainformações sobre a entidade implícita na solicitação sem transferir o próprio corpo da entidade. Este método é freqüentemente usado para testar links de hipertexto quanto à validade, acessibilidade e modificações recentes.

Parece-me que a resposta correta à pergunta do solicitante é que isso depende do que é representado pelo protocolo REST. Por exemplo, no meu caso particular, meu protocolo REST é usado para recuperar imagens bastante grandes (como em mais de 10K). Se eu tiver um grande número desses recursos sendo verificados constantemente, e considerando que uso os cabeçalhos de solicitação, faria sentido usar a solicitação HEAD, de acordo com as recomendações do w3.org.

Charles Thomas
fonte
14

Eu desencorajo fortemente esse tipo de abordagem.

Um serviço RESTful deve respeitar a semântica dos verbos HTTP. O verbo GET serve para recuperar o conteúdo do recurso, enquanto o verbo HEAD não retornará nenhum conteúdo e pode ser usado, por exemplo, para ver se um recurso mudou, saber seu tamanho ou tipo, para verificar se ele existe, e assim por diante.

E lembre-se: a otimização inicial é a raiz de todos os males.

Eric Citaire
fonte
8

Seu desempenho dificilmente mudará usando uma solicitação HEAD em vez de uma solicitação GET.

Além disso, quando você deseja que seja REST-ful e deseja obter dados, deve usar uma solicitação GET em vez de uma solicitação HEAD.

jabbink
fonte
8

GET busca cabeça + corpo, HEAD busca apenas cabeça. Não deve ser uma questão de opinião qual é o mais rápido. Eu não entendo as respostas votadas acima. Se você estiver procurando por informações META, então vá para HEAD, que é destinado a esse propósito.

Viktor Joras
fonte
3

Não entendo sua preocupação com o 'fluxo do corpo sendo aberto / fechado'. O corpo da resposta estará no mesmo fluxo que os cabeçalhos de resposta http e NÃO criará uma segunda conexão (que, a propósito, está mais na faixa de 3-6 ms).

Isso parece uma tentativa de otimização muito prematura em algo que simplesmente não fará uma diferença significativa ou mesmo mensurável. A verdadeira diferença é a conformidade com REST em geral, que recomenda o uso de GET para obtenção de dados.

Minha resposta é NÃO, use GET se fizer sentido, não há ganho de desempenho usando HEAD.

quebra
fonte
Suponha que o conteúdo tenha 100 MB. Certamente a cabeça terá menos do que o conteúdo em tamanho. Agora quando solicitamos esse recurso pelo método GET ou HEAD em sua opinião não há diferença de desempenho entre eles ?!
Mohammad Afrashteh
3
O OP declarou 250 caracteres no corpo da resposta. Não 100 MB. Essa é uma questão totalmente diferente.
smassey
1

As solicitações HEAD são como as solicitações GET , exceto que o corpo da resposta está vazio. Esse tipo de solicitação pode ser usado quando tudo o que você deseja são metadados sobre um arquivo, mas não precisa transportar todos os dados do arquivo.

Shadab Ali
fonte
-1

Você pode facilmente fazer um pequeno teste para medir o desempenho sozinho. Acho que a diferença de desempenho seria insignificante, porque se você estiver retornando apenas 'Y' ou 'N' no corpo, é um único byte extra anexado a um fluxo já aberto.

Eu também escolheria GET, pois é mais correto. Você não deve retornar conteúdo em cabeçalhos HTTP, apenas metadados.

AshleysBrain
fonte
GET - não é apenas um misterioso "byte extra único". Apenas corpo inteiro! No caso de um documento grande, pode ter alguns megabytes.
porfirion